复习 509 斐波那契数 1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int fib (int n) { if (n <= 1 ) return n; int [] dp = new int [n + 1 ]; dp[0 ] = 0 ; dp[1 ] = 1 ; for (int i = 2 ; i < n + 1 ; i++){ dp[i] = dp[i - 1 ] + dp[i - 2 ]; } return dp[n]; } }
70 爬楼梯 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int climbStairs (int n) { if (n <= 2 ) return n; int [] dp = new int [n + 1 ]; dp[1 ] = 1 ; dp[2 ] = 2 ; for (int i = 3 ; i < n + 1 ; i++){ dp[i] = dp[i - 1 ] + dp[i - 2 ]; } return dp[n]; } }
746 使用最小花费爬楼梯 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int minCostClimbingStairs (int [] cost) { int n = cost.length; if (n <= 1 ) return 0 ; int [] dp = new int [n + 1 ]; dp[0 ] = 0 ; dp[1 ] = 0 ; for (int i = 2 ; i < n + 1 ; i++){ dp[i] = Math.min(dp[i - 1 ] +cost[i - 1 ], dp[i - 2 ] + cost[i - 2 ]); } return dp[n]; } }
62 不同路径 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int uniquePaths (int m, int n) { int [][] dp = new int [m][n]; for (int i = 0 ; i < m; i++){ dp[i][0 ] = 1 ; } for (int i = 0 ; i < n; i++){ dp[0 ][i] = 1 ; } for (int i = 1 ; i < m; i++){ for (int j = 1 ; j < n; j++){ dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ]; } } return dp[m - 1 ][n - 1 ]; } }
63 不同路径II 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int uniquePathsWithObstacles (int [][] obstacleGrid) { int m = obstacleGrid.length; int n = obstacleGrid[0 ].length; int [][] dp = new int [m][n]; for (int i = 0 ; i < m && obstacleGrid[i][0 ] != 1 ; i++){ dp[i][0 ] = 1 ; } for (int i = 0 ; i < n && obstacleGrid[0 ][i] != 1 ; i++){ dp[0 ][i] = 1 ; } for (int i = 1 ; i < m; i++){ for (int j = 1 ; j < n; j++){ if (obstacleGrid[i][j] != 1 ){ dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ]; } } } return dp[m - 1 ][n - 1 ]; } }
343 拆分整数 动态规划5部曲:
dp[i] 表示,拆分i时最大乘积是多少
递推公式 一种是两个数:j 和 i-j 的乘积 另一种两个数以上:j 和 dp[i-j]的乘积 再算上每次对dp[i]的赋值比较
dp初始化 只考虑dp[2] = 1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int integerBreak (int n) { int [] dp = new int [n + 1 ]; dp[2 ] = 1 ; for (int i = 3 ; i < n + 1 ; i++){ for (int j = 1 ; j <= i - j; j++){ dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j])); } } return dp[n]; } }
96 不同的二叉搜索树
dp[i]表示,有多少不同的二叉搜索树
递推公式 以dp[3]为例: 头节点为1 右子树2个元素 * 左子树有0个搜索树 头节点为2 右子树1个 * 左子树1个 头节点为3 右子树0个 * 左子树2个
2个元素 dp[2] 1个元素 dp[1] 0个元素 dp[0]
dp[3] = dp[2]*dp[0] + dp[1]*dp[1] + dp[0] * dp[2]; dp[4] = 30 21 12 03;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int numTrees (int n) { int [] dp = new int [n +1 ]; dp[0 ] = 1 ; for (int i = 1 ; i <= n; i++){ for (int j = 1 ; j <= i; j++){ dp[i] += dp[j - 1 ] * dp[i - j]; } } return dp[n]; } }
每日一题 387 First Unique Character in a String: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int firstUniqChar (String s) { int [] record = new int [26 ]; for (int i = 0 ; i < s.length(); i++){ record[s.charAt(i) - 'a' ]++; } for (int i = 0 ; i < s.length(); i++){ if (record[s.charAt(i) - 'a' ] == 1 ){ return i; } } return -1 ; } }
每日一题 49 Group Anagrams 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public List<List<String>> groupAnagrams (String[] strs) { Map<String, List<String>> map = new HashMap <>(); for (String i :strs){ char [] chars = i.toCharArray(); Arrays.sort(chars); String str = new String (chars); if (!map.containsKey(str)){ map.put(str, new ArrayList <String>()); } map.get(str).add(i); } return new ArrayList <>(map.values()); } }