Leetcode--221--Maximal Square
方法一:
对于方阵中的每个点来说,先看纵向最多有多少个连续的1(例如:k个),然后从k到2开始枚举正方形的边长(设为j),每次判断能否形成一个正方形的时候去判断这j行是否每行都有连续j个1 。
具体做法:
1. 对于每个点统计以这个点为起点,横向有多少个1,纵向有多少个1,并得到分别得到两个矩阵。
2. 按照之前的普通思路进行判断
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import math 2 def get_1_0_matrix(mat): 3 new_mat_row = [] 4 new_mat_col = [] 5 new_mat_all_col = [] 6 rows = len(mat) 7 cols = len(mat[0]) 8 #get the rows of 1 9 for i in range(rows): 10 new_mat_row.append([]) 11 new_mat_col.append([]) 12 new_mat_all_col.append([]) 13 cnt_step = 0 14 for j in range(cols): 15 if cnt_step>0: 16 cnt_step -= 1 17 else: 18 if mat[i][j]=='1': 19 cnt_1 = 1 20 for k in range(j+1,cols): 21 if mat[i][k]=='1': 22 cnt_1 += 1 23 cnt_step += 1 24 else: 25 break 26 for k in range(j,j+cnt_1): 27 #new_mat_row[i][k] = chr(cnt_1) 28 #new_mat_row[i] += str(cnt_1) 29 new_mat_row[i].append(cnt_1) 30 cnt_1 -= 1 31 else: 32 #new_mat_row[i] += "0" 33 new_mat_row[i].append(0) 34 #get the cols of 1 35 for i in range(cols): 36 cnt_step = 0 37 for j in range(rows): 38 if cnt_step>0: 39 cnt_step -= 1 40 else: 41 if mat[j][i]=='1': 42 cnt_1 = 1 43 for k in range(j+1,rows): 44 if mat[k][i]=='1': 45 cnt_1 += 1 46 cnt_step += 1 47 else: 48 break 49 #print "cnt1:",cnt_1 50 cnt_1_bk = cnt_1 51 for k in range(j,j+cnt_1): 52 #new_mat_col[k] += str(cnt_1) 53 new_mat_col[k].append(cnt_1) 54 new_mat_all_col[k].append(cnt_1_bk) 55 #print "k:",k 56 cnt_1 -= 1 57 #print new_mat_col 58 else: 59 #new_mat_col[j] += "0" 60 new_mat_col[j].append(0) 61 new_mat_all_col[j].append(0) 62 return new_mat_row, new_mat_col, new_mat_all_col 63 class Solution(object): 64 def maximalSquare(self, matrix): 65 """ 66 :type matrix: List[List[str]] 67 :rtype: int 68 """ 69 if len(matrix)==0: 70 return 0 71 mat_row, mat_col, mat_all_col = get_1_0_matrix(matrix) 72 #print mat_row 73 #print mat_col 74 ans = 0 75 #print "rows =",len(mat), "cols =",len(mat[0]) 76 for i in range(len(matrix)): 77 for j in range(len(matrix[i])): 78 for length in range(mat_col[i][j],int(math.sqrt(ans)),-1): 79 flag = -1 80 for k in range(i,i+length): 81 if mat_row[k][j]<length: 82 flag = 1 83 break 84 if flag == -1: 85 ans = max(ans, length**2) 86 break 87 return ans 88 89 if __name__ == "__main__": 90 mat = ["1111111111111101001111111100111011111111","1111011011111111101101111101111111111111","0111101011111101101101101111111111111111","0101101011111111111101111111010110111111","1111111111110111110110010111111111111111","1111111110110101111111111101011111101111","0110110101110011111111111111110111110101","0111111111111100111111100110011011010101","1111011110111111111011011011110101101011","1111111110111111111101101101110111101111","1110110011111111111100111111111111111111","1011111110111101111001110111111111111111","0110111111111111101111110111011111011111","1111111111111111011111111111110111111011","1111100111111110101100111111111111101111","1111101111111110111111011111111111011111","1111101111111111111111011001111110011111","1111110111111111011111111111110111110111","1011111111111111010111110010111110111111","1111110011111111111110111111111111111011","1111111111111111110111011111011111011011","1100011011111111111111011111011111111111","1111101011111111111101100101110011111111","1110010111111111111011011110111101111101","1111111111111101101111111111101111111111","1111111011111101111011111111111110111111","1110011111111110111011111111110111110111","1111111111111100111111010111111111110111","1111111111111111111111000111111111011101","1111110111111111111111111101100111011011","1111011011111101101101111110111111101111","1111111111011111111111111111111111111111","1111111111111111111111111111111111111111","1100011111111110111111111111101111111011","1111101111111101111010111111111111111111","0111111111110011111111110101011011111111","1011011111101111111111101111111111110011","1010111111111111111111111111111110011111","0111101111011111111111111111110111111111","0111111011111111011101111011101111111111","0111111111110101111011111101011001111011","1111111111111011110111111101111111101110","1111101111111100111111111110111111001111","1101101111110101111101111111100111010100","0110111111100111110010111110111011011101"] 91 #mat = ["111","111","101"] 92 #mat = ["11110000","01111111","11111111","01111111","01111111","11111110","01111100","11111000"] 93 #new_mat_row, new_mat_col = get_1_0_matrix(mat) 94 #print new_mat_row 95 #print new_mat_col 96 s = Solution() 97 print s.maximalSquare(mat)
方法二:
dp[ i ][ j ]:表示以i ,j为右下角的正方形的边长
所以dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
a | b |
c | d |
如上图中,abcd分别表示各个正方形的右下角,且边长分别为abcd。开始分类讨论abc的大小:
if a>=b>=c:
所以d=c+1, 因为a+1>=c+1(即d) & b+1>=c+1(即d),所以自然的构成了新的正方形
if b>=c>=a 和 if c>=b>=a 同理可证
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Solution(object): 2 def maximalSquare(self, matrix): 3 """ 4 :type matrix: List[List[str]] 5 :rtype: int 6 """ 7 ans = 0 8 res = [] 9 for i in range(0,len(matrix)): 10 #print "i:",i 11 res.append([]) 12 for j in range(0,len(matrix[0])): 13 #print "j:",j 14 res[i].append(0) 15 for i in range(0,len(matrix)): 16 for j in range(0,len(matrix[0])): 17 if i ==0 or j==0: 18 if matrix[i][j]=='0': 19 res[i][j] = 0 20 else: 21 res[i][j] = 1 22 elif matrix[i][j]=='0': 23 res[i][j] = 0 24 else: 25 res[i][j] = 1+min(res[i][j-1],min(res[i-1][j-1],res[i-1][j])) 26 ans = max(ans,res[i][j]) 27 return ans**2
keep moving...