动态规划
Matrix DP
1 Triangle
public int minimumTotal(int[][] triangle) { if (triangle == null || triangle.length == 0) { return 0; } if (triangle.length == 1) { return triangle[0][0]; } int length = triangle.length; int[] num = new int[length]; for (int i = 0; i < length; i++) { num[i] = triangle[length - 1][i]; } for (int i = length - 2; i >= 0; i--) { for (int j = 0; j <= i; j++) { num[j] = Math.min(num[j], num[j + 1]) + triangle[i][j]; } } return num[0]; }
2 Minimum Path Sum
public int minPathSum(int[][] grid) { if (grid == null || grid.length == 0 || grid[0].length == 0) { return 0; } int m = grid.length; int n = grid[0].length; int[][] sum = new int[m][n]; sum[0][0] = grid[0][0]; for (int i = 1; i < n; i++) { sum[0][i] = sum[0][i - 1] + grid[0][i]; } for (int i = 1; i < m; i++) { sum[i][0] = sum[i - 1][0] + grid[i][0]; } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { sum[i][j] = Math.min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j]; } } return sum[m - 1][n - 1]; }
3 Unique Paths
public int uniquePaths(int m, int n) { if (m < 0 || n < 0) { return 0; } int[][] sum = new int[m][n]; for (int i = 0; i < n; i++) { sum[0][i] = 1; } for (int i = 0; i < m; i++) { sum[i][0] = 1; } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { sum[i][j] = sum[i - 1][j] + sum[i][j - 1]; } } return sum[m - 1][n - 1]; }
4 Unique Paths II
public int uniquePathsWithObstacles(int[][] obstacleGrid) { if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) { return 0; } int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] sum = new int[m][n]; for (int i = 0; i < n; i++) { if (obstacleGrid[0][i] == 1) { break; } sum[0][i] = 1; } for (int i = 0; i < m; i++) { if (obstacleGrid[i][0] == 1) { break; } sum[i][0] = 1; } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { if (obstacleGrid[i][j] == 1) { continue; } sum[i][j] = sum[i - 1][j] + sum[i][j - 1]; } } return sum[m - 1][n - 1]; }
Sequence DP
1 Climbing Stairs
public int climbStairs(int n) { // write your code here int f1 = 1; int f2 = 2; if (n == 1) { return f1; } if (n == 2) { return f2; } for (int i = 3; i <= n; i++) { int f3 = f1 + f2; f1 = f2; f2 = f3; } return f2; }
2 Jump Game
public boolean canJump(int[] a) { // wirte your code here if (a == null || a.length == 0) { return false; } int n = a.length; boolean[] can = new boolean[n]; can[0] = true; for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (can[j] && j + a[j] >= i) { can[i] = true; break; } } } return can[n - 1]; }
public boolean canJump(int[] a) { // wirte your code here if (a == null || a.length == 0) { return false; } int fastest = a[0]; for (int i = 1; i < a.length; i++) { if (fastest >= i && fastest < a[i] + i) { fastest = a[i] + i; } } return fastest >= a.length - 1; } }
3 Jump Game II
public int jump(int[] a) { // write your code here if (a == null || a.length == 0) { return 0; } int n = a.length; int[] step = new int[n]; step[0] = 0; for (int i = 1; i < n; i++) { step[i] = Integer.MAX_VALUE; for (int j = 0; j < i; j++) { if (step[j] != Integer.MAX_VALUE && j + a[j] >= i) { step[i] = Math.min(step[i], step[j] + 1); } } } return step[n - 1]; }
public int jump(int[] a) { // write your code here if (a == null || a.length == 0) { return 0; } int n = a.length; int start = 0; int end = 0; int jump = 0; while (end < n - 1) { jump++; int fastest = end; for (int i = start; i <= end; i++) { fastest = Math.max(fastest, i + a[i]); } start = end + 1; end = fastest; } return jump; }
4 Decode Ways
public int numDecodings(String s) { // Write your code here if (s == null || s.length() == 0 || s.charAt(0) == '0') { return 0; } int n = s.length(); int[] num = new int[n + 1]; num[0] = 1; num[1] = s.charAt(0) == '0' ? 0 : 1; for (int i = 2; i <= n; i++) { if (s.charAt(i - 1) != '0') { num[i] = num[i - 1]; } int twoDigit = (s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0'); if (twoDigit >= 10 && twoDigit <= 26) { num[i] += num[i - 2]; } } return num[n]; }
5 Palindrome Partitioning II
public int minCut(String s) { // write your code here if (s == null || s.length() == 0) { return 0; } boolean[][] dict = getDict(s); int[] res = new int[s.length() + 1]; res[0] = 0; for (int i = 0; i < s.length(); i++) { res[i + 1] = i + 1; for (int j = 0; j <= i; j++) { if (dict[j][i]) { res[i + 1] = Math.min(res[i + 1], res[j] + 1); } } } return res[s.length()] - 1; } public boolean[][] getDict(String s) { boolean[][] dict = new boolean[s.length()][s.length()]; for (int i = s.length() - 1; i >= 0; i--) { for (int j = i; j <= s.length() - 1; j++) { if (s.charAt(i) == s.charAt(j) && (j - i <= 2 || dict[i + 1][j - 1])) { dict[i][j] = true; } } } return dict; }
6 Word Break
public boolean wordBreak(String s, Set<String> dict) { if(s==null || s.length()==0) return true; boolean[] res = new boolean[s.length()+1]; res[0] = true; for(int i=1;i<=s.length();i++) { for (int j = 0; j < i; j++) { if (res[j] && dict.continues(s.substring(j, i)){ res[j] = true; break; } } } return res[s.length()]; } }
7 Longest Increasing Continuous Subsequence
public int longestIncreasingSubsequence(int[] nums) { // write your code here if (nums == null || nums.length == 0) return 0; int[] dp = new int[nums.length]; int max = 0; for (int i = 0; i < nums.length; i++){ dp[i] = 1; for (int j = 0; j < i; j++){ if (nums[j] < nums[i]){ dp[i] = Math.max(dp[i], dp[j] + 1); } max = Math.max(max, dp[i]); } } return max; }
two Sequence DP
1 Longest Common Subsequence
public int longestCommonSubsequence(String a, String b) { // write your code here if (a == null || b == null || a.length() == 0 || b.length() == 0) { return 0; } int m = a.length(); int n = b.length(); int[][] dp = new int[m + 1][n + 1]; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (a.charAt(i - 1) == b.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[m][n]; }
2 Edit Distance
public static int minDistance(String word1, String word2) { int m = word1.length(); int n = word2.length(); int[][] dp = new int[m + 1][n + 1]; for (int i = 0; i <= n; i++) { dp[0][i] = i; } for (int i = 0; i <= m; i++) { dp[i][0] = i; } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (word1.charAt(i - 1) == word2.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1; } } } return dp[m][n]; }
3 Distinct Subsequences
public int numDistinct(String s, String t) { int m = s.length(); int n = t.length(); int[][] dp = new int[m + 1][n + 1]; for (int i = 0; i <= m; i++) { dp[i][0] = 1; } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { dp[i][j] = dp[i - 1][j]; if (s.charAt(i - 1) == t.charAt(j - 1)) { dp[i][j] += dp[i - 1][j - 1]; } } } return dp[m][n]; }
4 Interleaving String
public boolean isInterleave(String s1, String s2, String s3) { // write your code here if (s1.length() + s2.length() != s3.length()) { return false; } int m = s1.length(); int n = s2.length(); boolean[][] dp = new boolean[m + 1][n + 1]; dp[0][0] = true; for (int i = 1; i <= n; i++) { if (dp[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1)) { dp[0][i] = true; } } for (int i = 1; i <= m; i++) { if (dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1)) { dp[i][0] = true; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1) || dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)) { dp[i][j] = true; } } } return dp[m][n]; }