搜索二维矩阵 II
搜索二维矩阵 II
解题思路
对每一行进行二分查找
从二维矩阵的右上角开始,会发现每次都是向左数字会变小,向下数字会变大,有点和二分查找树相似。所以可以把target
与当前值进行比较:
- 如果
target
大于当前值,向下走
- 如果
target
小于当前值,向左走
- 如果
target
等于当前值,返回true
解题代码
- 对每一行进行二分查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| func searchMatrix(matrix [][]int, target int) bool { for _, row := range matrix { if biSearch(row, target) { return true } }
return false }
func biSearch(nums []int, target int) bool { low, high := 0, len(nums)-1 for low <= high { mid := (low+high) / 2 if nums[mid] == target { return true } else if nums[mid] < target { low = mid + 1 } else { high = mid - 1 } }
return false }
|
- 从二维矩阵的右上角开始查找,与二分查找树类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func searchMatrix(matrix [][]int, target int) bool { row, col := 0, len(matrix[0])-1 for row < len(matrix) && col >= 0 { cur := matrix[row][col] if target > cur { row++ } else if target < cur { col-- } else { return true } }
return false }
|
最大正方形
最大正方形
解题思路
利用动态规划,设dp[i][j]
为以matrix[i][j]
为右下角的只包含1
的正方形的边长:
初始化dp
数组:
- 若
matrix[i][0] == '1'
,dp[i][0] = 1
,否则为0
- 若
matrix[0][j] == '1'
,dp[0][j] = 1
,否则为0
更新dp
数组:
- 若
matrix[i][j] == '1'
,dp[i][0] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])
- 若
matrix[i][j] == '0'
,dp[0][j] = 0
利用遍历max
记录最长的边长即可,最大面积 = 边长 * 边长
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| func maximalSquare(matrix [][]byte) int { m := len(matrix) n := len(matrix[0]) max := 0 dp := make([][]int, m) for i := 0; i < m; i++ { dp[i] = make([]int, n) } for i := 0; i < m; i++ { if matrix[i][0] == '1' { dp[i][0] = 1 max = 1 } else { dp[i][0] = 0 } } for j := 0; j < n; j++ { if matrix[0][j] == '1' { dp[0][j] = 1 max = 1 } else { dp[0][j] = 0 } } for i := 1; i < m; i++ { for j := 1; j < n; j++ { if matrix[i][j] == '1' { dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) if dp[i][j] > max { max = dp[i][j] } } else { dp[i][j] = 0 } } }
return max * max }
func min(n1, n2, n3 int) int { if n1 < n2 { if n1 < n3 { return n1 } else { return n3 } } else { if n2 < n3 { return n2 } else { return n3 } } }
|
最长公共前缀
最长公共前缀
解题思路
扫描字符串组中的每一列:
- 若当前列上的所有字符相同,就将当前字符加入到公共前缀中去
- 否则,直接返回当前的公共前缀
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| func longestCommonPrefix(strs []string) string { var commomPrefix string i := 0 for i < len(strs[0]) { cur := strs[0][i] for j := 1; j < len(strs); j++ { if i >= len(strs[j]) || strs[j][i] != cur { return commomPrefix } } commomPrefix += string(cur) i++ } return commomPrefix }
|
岛屿的最大面积
岛屿的最大面积
解题思路
将矩阵grid
看作是一个图,图中的每一个顶点都有上下左右四条边相连。把1
看作是连同分量的顶点,那么计算岛屿的面积就是遍历这个图中所有连通分量所包含的顶点数目:
- 基于深度优先遍历
- 基于广度优先遍历
解题代码
- 深度优先遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| func maxAreaOfIsland(grid [][]int) int { m := len(grid) n := len(grid[0]) max := 0 var cur int var dfs func(i, j int) dfs = func(i, j int) { if i < 0 || i >= m || j < 0 || j >= n { return } if grid[i][j] == 0 { return } else { cur++ grid[i][j] = 0 dfs(i-1, j) dfs(i+1, j) dfs(i, j-1) dfs(i, j+1) } } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == 1 { cur = 0 dfs(i, j) if cur > max { max = cur } } } }
return max }
|
- 广度优先遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| func maxAreaOfIsland(grid [][]int) int { m := len(grid) n := len(grid[0]) max := 0 var bfs func(i, j int) int bfs = func(i, j int) int { var cur int queue := make([][]int, 0) queue = append(queue, []int{i, j})
for len(queue) > 0 { i, j = queue[0][0], queue[0][1] queue = queue[1:] if i < 0 || i >= m || j < 0 || j >= n { continue } if grid[i][j] == 1 { grid[i][j] = 0 cur++ queue = append(queue, []int{i-1, j}) queue = append(queue, []int{i+1, j}) queue = append(queue, []int{i, j-1}) queue = append(queue, []int{i, j+1}) } }
return cur } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == 1 { cur := bfs(i, j) if cur > max { max = cur } } } }
return max }
|