נתון א n × n מטריצה בינארית יחד עם מורכב מ 0s ו 1 שניות . המשימה שלך היא למצוא את הגודל של הגדול ביותר '+' צורה שניתן ליצור רק באמצעות 1 שניות .
א '+' הצורה מורכבת מתא מרכזי עם ארבע זרועות הנמשכות לכל ארבעת הכיוונים ( למעלה למטה ימינה ושמאלה ) תוך הישארות בגבולות המטריצה. הגודל של א '+' מוגדר כ- המספר הכולל של תאים יוצרים אותו כולל המרכז וכל הזרועות.
עץ חיפוש בינארי
המשימה היא להחזיר את גודל מקסימלי מכל תקף '+' ב יחד עם . אם לא '+' יכול להיווצר חזרה .
דוגמאות:
קֶלֶט: עם = [ [0 1 1 0 1] [0 0 1 1 1] [1 1 1 1 1] [1 1 1 0 1] [0 1 1 1 0] ]
תְפוּקָה: 9
הֶסבֵּר: ניתן ליצור '+' באורך זרוע של 2 (2 תאים לכל כיוון + מרכז אחד) במרכז המחצלת.
0 1 1 0 1
0 0 1 1 1
1 1 1 1 1
1 1 1 0 1
0 1 1 1 0
גודל כולל = (2 × 4) + 1 = 9
קֶלֶט: עם = [ [0 1 1] [0 0 1] [1 1 1] ]
תְפוּקָה: 1
הֶסבֵּר: '+' באורך זרוע של 0 (0 תאים לכל כיוון + מרכז אחד) יכול להיווצר עם כל אחד מה-1.קֶלֶט: עם = [ [0] ]
תְפוּקָה:
הֶסבֵּר: לֹא סימן '+' יכול להיווצר.
[גישה נאיבית] - התייחס לכל נקודה כמרכז - O(n^4) זמן ו-O(n^4) מרחב
חצו את תאי המטריצה בזה אחר זה. ראה כל נקודה שעברה כמרכז של פלוס ומצא את גודל ה-+. עבור כל אלמנט אנו חוצים שמאל ימין למטה ולמעלה. המקרה הגרוע ביותר בפתרון הזה קורה כשיש לנו את כל ה-1.
[גישה צפויה] - חשב מראש 4 מערכים - O(n^2) זמן ו-O(n^2) מרחב
ה רַעְיוֹן הוא לשמור על ארבע מטריצות עזר שמאל[][] ימין[][] למעלה[][] למטה[][] לאחסן 1'ים רצופים בכל כיוון. לכל תא (i j) במטריצת הקלט אנו מאחסנים מידע למטה באלה ארבע מטריצות -
- שמאלה (i j) מאחסן את המספר המרבי של 1 רצופות ל- שְׁמֹאל של תא (i j) כולל תא (i j).
- מימין (i j) מאחסן את המספר המרבי של 1 רצופות ל- יָמִינָה של תא (i j) כולל תא (i j).
- top(i j) מאחסן את המספר המרבי של 1 רצוף ב רֹאשׁ
- תחתית (i j) מאחסן את המספר המרבי של 1 רצוף ב תַחתִית של תא (i j) כולל תא (i j).
לאחר חישוב ערך עבור כל תא של מטריצות לעיל, הגדול ביותר'+' יווצר על ידי תא של מטריצת קלט שיש לו ערך מקסימלי על ידי התחשבות במינימום של ( left(i j) right(i j) top(i j) bottom(i j) )
אנחנו יכולים להשתמש תכנות דינמי כדי לחשב את הכמות הכוללת של 1ים עוקבים בכל כיוון:
if mat(i j) == 1
left(i j) = left(i j - 1) + 1else left(i j) = 0
יישר תמונת css
if mat(i j) == 1
top(i j) = top(i - 1 j) + 1;else top(i j) = 0;
if mat(i j) == 1
bottom(i j) = bottom(i + 1 j) + 1;else bottom(i j) = 0;
if mat(i j) == 1
right(i j) = right(i j + 1) + 1;else right(i j) = 0;
להלן יישום הגישה לעיל:
C++// C++ program to find the largest '+' in a binary matrix // using Dynamic Programming #include using namespace std; int findLargestPlus(vector<vector<int>> &mat) { int n = mat.size(); vector<vector<int>> left(n vector<int>(n 0)); vector<vector<int>> right(n vector<int>(n 0)); vector<vector<int>> top(n vector<int>(n 0)); vector<vector<int>> bottom(n vector<int>(n 0)); // Fill left and top matrices for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { left[i][j] = (j == 0) ? 1 : left[i][j - 1] + 1; top[i][j] = (i == 0) ? 1 : top[i - 1][j] + 1; } } } // Fill right and bottom matrices for (int i = n - 1; i >= 0; i--) { for (int j = n - 1; j >= 0; j--) { if (mat[i][j] == 1) { right[i][j] = (j == n - 1) ? 1 : right[i][j + 1] + 1; bottom[i][j] = (i == n - 1) ? 1 : bottom[i + 1][j] + 1; } } } int maxPlusSize = 0; // Compute the maximum '+' size for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { int armLength = min({left[i][j] right[i][j] top[i][j] bottom[i][j]}); maxPlusSize = max(maxPlusSize (4 * (armLength - 1)) + 1); } } } return maxPlusSize; } int main() { // Hardcoded input matrix vector<vector<int>> mat = { {0 1 1 0 1} {0 0 1 1 1} {1 1 1 1 1} {1 1 1 0 1} {0 1 1 1 0} }; cout << findLargestPlus(mat) << endl; return 0; }
Java // Java program to find the largest '+' in a binary matrix // using Dynamic Programming class GfG { static int findLargestPlus(int[][] mat) { int n = mat.length; int[][] left = new int[n][n]; int[][] right = new int[n][n]; int[][] top = new int[n][n]; int[][] bottom = new int[n][n]; // Fill left and top matrices for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { left[i][j] = (j == 0) ? 1 : left[i][j - 1] + 1; top[i][j] = (i == 0) ? 1 : top[i - 1][j] + 1; } } } // Fill right and bottom matrices for (int i = n - 1; i >= 0; i--) { for (int j = n - 1; j >= 0; j--) { if (mat[i][j] == 1) { right[i][j] = (j == n - 1) ? 1 : right[i][j + 1] + 1; bottom[i][j] = (i == n - 1) ? 1 : bottom[i + 1][j] + 1; } } } int maxPlusSize = 0; // Compute the maximum '+' size for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { int armLength = Math.min(Math.min(left[i][j] right[i][j]) Math.min(top[i][j] bottom[i][j])); maxPlusSize = Math.max(maxPlusSize (4 * (armLength - 1)) + 1); } } } return maxPlusSize; } public static void main(String[] args) { // Hardcoded input matrix int[][] mat = { {0 1 1 0 1} {0 0 1 1 1} {1 1 1 1 1} {1 1 1 0 1} {0 1 1 1 0} }; System.out.println(findLargestPlus(mat)); } }
Python # Python program to find the largest '+' in a binary matrix # using Dynamic Programming def findLargestPlus(mat): n = len(mat) left = [[0] * n for i in range(n)] right = [[0] * n for i in range(n)] top = [[0] * n for i in range(n)] bottom = [[0] * n for i in range(n)] # Fill left and top matrices for i in range(n): for j in range(n): if mat[i][j] == 1: left[i][j] = 1 if j == 0 else left[i][j - 1] + 1 top[i][j] = 1 if i == 0 else top[i - 1][j] + 1 # Fill right and bottom matrices for i in range(n - 1 -1 -1): for j in range(n - 1 -1 -1): if mat[i][j] == 1: right[i][j] = 1 if j == n - 1 else right[i][j + 1] + 1 bottom[i][j] = 1 if i == n - 1 else bottom[i + 1][j] + 1 maxPlusSize = 0 # Compute the maximum '+' size for i in range(n): for j in range(n): if mat[i][j] == 1: armLength = min(left[i][j] right[i][j] top[i][j] bottom[i][j]) maxPlusSize = max(maxPlusSize (4 * (armLength - 1)) + 1) return maxPlusSize if __name__ == '__main__': # Hardcoded input matrix mat = [ [0 1 1 0 1] [0 0 1 1 1] [1 1 1 1 1] [1 1 1 0 1] [0 1 1 1 0] ] print(findLargestPlus(mat))
C# // C# program to find the largest '+' in a binary matrix // using Dynamic Programming using System; class GfG { static int FindLargestPlus(int[] mat) { int n = mat.GetLength(0); int[] left = new int[n n]; int[] right = new int[n n]; int[] top = new int[n n]; int[] bottom = new int[n n]; // Fill left and top matrices for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i j] == 1) { left[i j] = (j == 0) ? 1 : left[i j - 1] + 1; top[i j] = (i == 0) ? 1 : top[i - 1 j] + 1; } } } // Fill right and bottom matrices for (int i = n - 1; i >= 0; i--) { for (int j = n - 1; j >= 0; j--) { if (mat[i j] == 1) { right[i j] = (j == n - 1) ? 1 : right[i j + 1] + 1; bottom[i j] = (i == n - 1) ? 1 : bottom[i + 1 j] + 1; } } } int maxPlusSize = 0; // Compute the maximum '+' size for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (mat[i j] == 1) { int armLength = Math.Min(Math.Min(left[i j] right[i j]) Math.Min(top[i j] bottom[i j])); maxPlusSize = Math.Max(maxPlusSize (4 * (armLength - 1)) + 1); } } } return maxPlusSize; } public static void Main() { // Hardcoded input matrix int[] mat = { {0 1 1 0 1} {0 0 1 1 1} {1 1 1 1 1} {1 1 1 0 1} {0 1 1 1 0} }; Console.WriteLine(FindLargestPlus(mat)); } }
JavaScript // JavaScript program to find the largest '+' in a binary matrix // using Dynamic Programming function findLargestPlus(mat) { let n = mat.length; let left = Array.from({ length: n } () => Array(n).fill(0)); let right = Array.from({ length: n } () => Array(n).fill(0)); let top = Array.from({ length: n } () => Array(n).fill(0)); let bottom = Array.from({ length: n } () => Array(n).fill(0)); // Fill left and top matrices for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { if (mat[i][j] === 1) { left[i][j] = (j === 0) ? 1 : left[i][j - 1] + 1; top[i][j] = (i === 0) ? 1 : top[i - 1][j] + 1; } } } // Fill right and bottom matrices for (let i = n - 1; i >= 0; i--) { for (let j = n - 1; j >= 0; j--) { if (mat[i][j] === 1) { right[i][j] = (j === n - 1) ? 1 : right[i][j + 1] + 1; bottom[i][j] = (i === n - 1) ? 1 : bottom[i + 1][j] + 1; } } } let maxPlusSize = 0; // Compute the maximum '+' size for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { if (mat[i][j] === 1) { let armLength = Math.min(left[i][j] right[i][j] top[i][j] bottom[i][j]); maxPlusSize = Math.max(maxPlusSize (4 * (armLength - 1)) + 1); } } } return maxPlusSize; } // Hardcoded input matrix let mat = [ [0 1 1 0 1] [0 0 1 1 1] [1 1 1 1 1] [1 1 1 0 1] [0 1 1 1 0] ]; console.log(findLargestPlus(mat));
תְפוּקָה
9
מורכבות זמן: O(n²) עקב ארבע מעברים לחישוב המטריצות הכיווניות ומעבר אחד אחרון לקביעת ה-'+' הגדול ביותר. כל מעבר לוקח זמן O(n²) המוביל למורכבות כוללת של O(n²).
מורכבות החלל: O(n²) עקב ארבע מטריצות עזר (שמאל ימין למעלה למטה) שצורכות שטח נוסף של O(n²).