最小路径和
最小路径和
解题思路
利用动态规划,dp[i][j]表示总左上角到grid[i][j]的最小路径和。其中:
dp[0][0] = grid[0][0] 
dp[i][0] =  dp[i-1][0] + grid[i][0] 
dp[0][j] = dp[0][j-1] + grid[0][j] 
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] 
解题代码
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
   | func minPathSum(grid [][]int) int {     m := len(grid)     n := len(grid[0])          dp := make([][]int, m)     for i := 0; i < m; i++ {         dp[i] = make([]int, n)     }     dp[0][0] = grid[0][0]          for i := 1; i < m; i++ {         dp[i][0] = dp[i-1][0] + grid[i][0]     }     for j := 1; j < n; j++ {         dp[0][j] = dp[0][j-1] + grid[0][j]     }          for i := 1; i < m; i++ {         for j := 1; j < n; j++ {             dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]         }     }
      return dp[m-1][n-1] }
  func min(n1, n2 int) int {     if n1 < n2 {         return n1     } else {         return n2     } }
  | 
 
组合总和
组合总和
解题思路
利用回溯算法
- 首先对
candidates进行排序,使之递增有序 
- 可以将结果看作一棵
len(candidates)叉树,第i个分支对应选择candidates[i],并且每次i从startIndex开始,这样可以避免重复结果 
解题代码
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
   | func combinationSum(candidates []int, target int) [][]int {     sort.Ints(candidates)        res := make([][]int, 0)          path := make([]int, 0)              var backtrack func(curSum int, startIntdex int)     backtrack = func(curSum int, startIntdex int) {               if curSum == target {                          temp := make([]int, len(path))             copy(temp, path)             res = append(res, temp)         }                  for i:= startIntdex; i < len(candidates); i++{             if curSum+candidates[i] > target {                 break             }             path = append(path, candidates[i])                backtrack(curSum+candidates[i], i)                          path = path[:len(path)-1]         }     }
      backtrack(0, 0)    
      return res
  }
  | 
 
子集
子集
解题思路
利用回溯算法,求所有的子集
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | func subsets(nums []int) [][]int {     res := make([][]int, 0)          path := make([]int, 0)       var backtrack func(startIndex int)     backtrack = func(startIndex int) {           temp := make([]int, len(path))         copy(temp, path)         res = append(res, temp)                       for i := startIndex; i < len(nums); i++ {             path = append(path, nums[i])                 backtrack(i+1)                          path = path[:len(path)-1]         }     }
      backtrack(0)    
      return res }
  | 
 
不同路径
不同路径
解题思路
利用动态规划,记网格为grid[i][j],dp[i][j]表示到达grid[i][j]的路径条数。
故对于dp的初始化:
dp[i][0] = 1 
dp[0][j] = 1 
对他dp的更新:
dp[i][j] = dp[i-1][j] + dp[i][j-1] 
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | func uniquePaths(m int, n int) int {          dp := make([][]int, m)     for i := 0; i < m; i++ {         dp[i] = make([]int, n)     }          dp[0][0] = 1     for i := 1; i < m; i++ {             dp[i][0] = 1     }     for j := 1; j < n; j++ {             dp[0][j] = 1     }          for i := 1; i < m; i++ {         for j := 1; j < n; j++ {             dp[i][j] = dp[i-1][j] + dp[i][j-1]         }     }
      return dp[m-1][n-1] }
  |