1. Change
class Solution { public int coinChange(int[] coins, int amount) { int n = coins.length; int[] arr = new int[amount + 1];// 0..amount // Define initial conditions arr[0] = 0; for(int i = 1; i <= amount; i++) { // Find arr[i] arr[i] = Integer.MAX_VALUE; for(int j = 0; j < n; j++) { if(i >= coins[j] && arr[i - coins[j]] != Integer.MAX_VALUE && arr[i - coins[j]] + 1 < arr[i]) { arr[i] = arr[i - coins[j]] + 1; } } } if (arr[amount] == Integer.MAX_VALUE) { return -1; }else { return arr[amount]; } } }
2. Different paths - 1
analysis:
The first step of dynamic planning: determine the status
a. The last step: no matter how the robot finally reaches the end, there are only two cases in the last step, that is, from left to right and from top to bottom. If the target position is [m - 1][n -1], it comes from [m-2][n-1] and [m - 1][n - 2].
b. Subproblem. The original problem is from [0] [0] to [m-1][n-1] into how many ways from [0] [0] to [m-2][n-1] and how many ways from [0] [0] to [m-1][n-2]
The second step of dynamic programming: state transition equation
f[i][j] = f[i - 1][j] + f[i][j - 1]
The third step of dynamic programming: initial conditions and boundary conditions
Initial condition: f[0][0] = 1
Boundary condition: when i = 0 or j = 0, you can only come from one direction, f [0] [J] = 1, f [i] [0] = 1
Step 4 of dynamic programming: calculation sequence
Calculate row 0
Calculate line 1
. . .
Calculate line m - 1
The answer is f[m - 1][n -1]
class Solution { public int uniquePaths(int m, int n) { int[][] arr = new int[m][n]; arr[0][0] = 1; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if (i == 0 || j == 0) { arr[i][j] = 1; }else{ arr[i][j] = arr[i][j - 1] + arr[i - 1][j]; } } } return arr[m - 1][n - 1]; } }
3. Different paths - 2
Analysis: the difference between this question and 1 is that the obstacle f[i][j] = 0, and then in the boundary conditions, the uppermost and leftmost are no longer directly equal to 1, but determined by the one in front of it!
The first step of dynamic planning: determine the status
a. The last step: no matter how the robot finally reaches the end, there are only two cases in the last step, that is, from left to right and from top to bottom. If the target position is [m - 1][n -1], it comes from [m-2][n-1] and [m - 1][n - 2].
b. Subproblem, the original problem is to change from [0] [0] to [m-1][n-1] into how many ways from [0] [0] to [m-2][n-1] and how many ways from [0] [0] to [m-1][n-2]
The second step of dynamic programming: state transition equation
f[i][j] = f[i - 1][j] + f[i][j - 1]
The third step of dynamic programming: initial conditions and boundary conditions
Initial condition: f[0][0] = 1
Boundary conditions: i = 0 or j = 0, f [i] [J] = f [i] [J - 1] or f[i - 1][j]
Step 4 of dynamic programming: calculation sequence
class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] arr = new int[m][n]; if(obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) { return 0; }else{ arr[0][0] = 1; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(obstacleGrid[i][j] == 1) { arr[i][j] = 0; }else{ if(i == 0 && j == 0){ arr[i][j] = 1; }else{ if(i == 0) { arr[i][j] = arr[i][j - 1]; } if(j == 0) { arr[i][j] = arr[i - 1][j]; } if(i != 0 && j != 0) { arr[i][j] = arr[i - 1][j]+ arr[i][j - 1]; } } } } } } return arr[m - 1][n - 1]; } }
4. Jumping game
analysis:
The first step of dynamic planning: determine the status
a. The last step: no matter how you get to the last step, you will jump directly from the previous step
b. For the subproblem, it can jump to the last step j successfully. The last jump is successful in position i, and the number of steps that can jump in position i can reach j
The second step of dynamic programming: state transition equation
f[j] = or{i = 0 to J-1} {f [i] & & nums [i] > J - I}
The third step of dynamic programming: initial conditions and boundary conditions
Initial condition: f[0]= true
Boundary conditions: None
Step 4 of dynamic programming: calculation sequence
From small to large.
class Solution { public boolean canJump(int[] nums) { // There are two conditions for f[j] to be true // 1. f[i] = true 2. nums[i] > j - i if (nums == null || nums.length == 0) return false; int n = nums.length; boolean[] arr = new boolean[n+1]; arr[0] = true; for(int i = 1; i < n; i++) { arr[i] = false; // Here is a small detail for(int j = 0; j < i; j++) { if(arr[j] && nums[j] >= i - j) { arr[i] = true; break; } } } return arr[n - 1]; } }
5. Paint the house
Paint the house 2. Please move to question 12
subject
analysis:
Sequential dynamic programming: first i minimum / number of modes / minimum
sequence ➕ state
class Solution { public int minCost(int[][] costs) { int n = costs.length;// Number of houses int[][] arr = new int[3][n]; //arr[0][i] represents the lowest price of the first I house when the I house is red // arr[1][i] represents the lowest price of the first I house when the I house is blue // arr[2][i] represents the lowest price of the first I house when the I house is green // initial condition for(int i = 0; i < 3; i++) { arr[i][0] = costs[0][i]; } for(int i = 1; i < n; i ++) { arr[0][i] = arr[1][i - 1] > arr[2][i - 1] ? arr[2][i - 1] + costs[i][0]: arr[1][i - 1] + costs[i][0]; arr[1][i] = arr[0][i - 1] > arr[2][i - 1] ? arr[2][i - 1] + costs[i][1]: arr[0][i - 1] + costs[i][1]; arr[2][i] = arr[0][i - 1] > arr[1][i - 1] ? arr[1][i - 1] + costs[i][2]: arr[0][i - 1] + costs[i][2]; } return getMin(arr[0][n - 1], arr[1][n - 1], arr[2][n - 1]); } public int getMin(int a, int b, int c) { int temp = a>b?b:a; return temp>c?c:temp; } }
6. Decoding method
My solution is very verbose
class Solution { public int numDecodings(String s) { if(s == null || s.charAt(0) == '0') { return 0; }else if(s.length() == 1 && s.charAt(0) != '0' ) { return 1; }else{ int n = s.length(); int[] arr = new int[n]; arr[0] = 1; if(s.charAt(0) == '1' && s.charAt(1) != '0') { // If the first one is 1 or 2 arr[1] = 2; }else if(s.charAt(0) == '2'&& Character.getNumericValue(s.charAt(1)) <= 6 && s.charAt(1) != '0') { arr[1] = 2; }else if(Character.getNumericValue(s.charAt(0))>= 3&& s.charAt(1) == '0') { // arr[1] = 0; return 0; }else if(s.charAt(0) == '0'&& s.charAt(1) == '0') { return 0; } else{ arr[1] = 1; } for(int i = 2; i < n; i++){ if(s.charAt(i - 1) == '1' && s.charAt(i) != '0') { // If the first one is 1 or 2 arr[i] = arr[i - 1] + arr[i - 2]; }else if(Character.getNumericValue(s.charAt(i - 1))>= 3 && s.charAt(i) == '0') { // arr[1] = 0; return 0; }else if(s.charAt(i - 1) == '0' && s.charAt(i) == '0') { return 0; } else if(s.charAt(i - 1) == '2' && Character.getNumericValue(s.charAt(i)) <= 6 && s.charAt(i) != '0') { arr[i] = arr[i - 1] + arr[i - 2]; }else if(s.charAt(i - 1) == '1' && s.charAt(i) == '0'){ arr[i] = arr[i - 2]; }else if (s.charAt(i - 1) == '2' && s.charAt(i) == '0'){ arr[i] = arr[i - 2]; }else{ arr[i] = arr[i - 1]; } } return arr[n - 1]; } } }
A relatively simple and skilled solution
class Solution { public int numDecodings(String s) { char[] ss = s.toCharArray(); int n = ss.length; if (n == 0) { return 0; } int[] arr = new int[n+1]; int m = ss[0] - '0'; arr[0] = 1; for(int i = 1; i <= n; i++) { arr[i] = 0; int t = ss[i - 1] - '0'; if(t >= 1 && t <= 9){ arr[i] += arr[i - 1]; } if(i >= 2) { int q = ss[i - 2] - '0'; int p = ss[i - 1] - '0'; if(q * 10 + p >= 10 && q * 10 + p <= 26) { arr[i] += arr[i - 2];// Learn well and wait } } } return arr[n]; } }
7. Longest continuous increasing subsequence
Coordinate dynamic programming
subject
class Solution { public int findLengthOfLCIS(int[] nums) { int n = nums.length; if(n == 0) { return 0; }else{ int[] arr = new int[n]; arr[0] = 1; int m = 1; for(int i = 1;i < n; i++) { if(nums[i]> nums[i - 1]){ arr[i] = arr[i - 1] + 1; }else{ arr[i] = 1; } if(m <= arr[i]){ m = arr[i]; } } return m; } } }
8. Minimum path and
class Solution { public int minPathSum(int[][] grid) { int m = grid.length; int n = grid[0].length; int[][] arr = new int[m][n]; arr[0][0] = grid[0][0]; for(int i = 1; i < m; i++) { arr[i][0] = arr[i - 1][0] + grid[i][0]; } for(int i = 1; i < n; i++) { arr[0][i] = arr[0][i - 1] + grid[0][i]; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { arr[i][j] = arr[i - 1][j] < arr[i][j - 1] ? grid[i][j] + arr[i - 1][j]: grid[i][j] + arr[i][j - 1]; } } return arr[m - 1][n - 1]; } }
9. Bomb the enemy
public static int maxKillEnemies(char[][] A) { if (A == null || A.length == 0 || A[0].length == 0) { return 0; } int m = A.length; int n = A[0].length; int[][] f = new int[m][n]; int[][] res = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { res[i][j] = 0; } } // up for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (A[i][j] == 'W') { f[i][j] = 0; }else { f[i][j] = 0; if (A[i][j] == 'E') { f[i][j] = 1; } if (i > 0) { f[i][j] += f[i - 1][j]; } } res[i][j] += f[i][j]; } } // down for (int i = m - 1; i >= 0; i--) { for (int j = n - 1; j >= 0; j--) { if (A[i][j] == 'W') { f[i][j] = 0; }else { f[i][j] = 0; if (A[i][j] == 'E') { f[i][j] = 1; } if (i < m - 1) { f[i][j] += f[i + 1][j]; } } res[i][j] += f[i][j]; } } // left for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (A[i][j] == 'W') { f[i][j] = 0; }else { f[i][j] = 0; if (A[i][j] == 'E') { f[i][j] = 1; } if (j > 0) { f[i][j] += f[i][j - 1]; } } res[i][j] += f[i][j]; } } // right for (int i = 0; i < m; i++) { for (int j = n - 1; j >= 0; j--) { if (A[i][j] == 'W') { f[i][j] = 0; }else { f[i][j] = 0; if (A[i][j] == 'E') { f[i][j] = 1; } if (j < n - 1) { f[i][j] += f[i][j + 1]; } } res[i][j] += f[i][j]; } } int result = Integer.MIN_VALUE; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (A[i][j] == '0') { result = result > res[i][j] ? result:res[i][j]; } } } return result; }
10. Yang Hui triangle
class Solution { public List<List<Integer>> generate(int numRows) { List<List<Integer>> dp = new ArrayList<List<Integer>>(); List<Integer> tmp = new ArrayList<Integer>(); tmp.add(1); dp.add(tmp); if(numRows == 1) { return dp; } List<Integer> tmp2 = new ArrayList<Integer>(); tmp2.add(1); tmp2.add(1); dp.add(tmp2); if(numRows == 2) { return dp; } for(int i = 2; i < numRows; i++) { List<Integer> t = new ArrayList<Integer>(); t.add(1); for(int j = 1; j < i; j++) { t.add(dp.get(i - 1).get(j - 1) + dp.get(i - 1).get(j)); } t.add(1); dp.add(t); } return dp; } }
11. Bit count
class Solution { public int[] countBits(int n) { if(n == 0) { return new int[]{0}; }else{ int[] dp = new int[n + 1]; dp[0] = 0; dp[1] = 1; for(int i = 2; i <= n; i++) { dp[i] = dp[i >> 1] + i % 2; } return dp; } } }
12. Painting the house 2
class Solution { public int minCostII(int[][] costs) { int n = costs.length; // n houses int k = costs[0].length; // k colors int[][] f = new int[n+1][k]; int min1, min2; int j1 = 0; int j2 = 0; // dp[i][j] I house before painting, and i-1 house is the minimum cost of j color for(int j = 0; j < k; j++) { f[0][j] = 0; } for(int i = 1; i <= n; i++) { //Minimum and sub minimum min1 = min2 = Integer.MAX_VALUE; for(int j = 0; j < k; j++) { if(f[i - 1][j] < min1) { min2 = min1; j2 = j1; min1 = f[i - 1][j]; j1 = j; }else{ if(f[i - 1][j] < min2) { min2 = f[i - 1][j]; j2 = j; } } } for(int j = 0; j < k; j++) { if(j == j1) { f[i][j] = costs[i - 1][j] + min2; }else{ f[i][j] = costs[i - 1][j] + min1; } } } int res = Integer.MAX_VALUE; for(int i = 0; i < k; i++) { res = res < f[n][i] ? res : f[n][i]; } return res; } }
13. House theft
class Solution { public int rob(int[] nums) { int n = nums.length; if(n == 1){ return nums[0]; }else if(n == 2){ return Math.max(nums[0], nums[1]); }else{ int[] f = new int[n]; f[0] = nums[0]; f[1] = Math.max(nums[0], nums[1]); for(int i = 2; i < n; i++) { f[i] = f[i - 2] + nums[i] > f[i - 1] ? f[i - 2] + nums[i] : f[i - 1]; } return f[n - 1]; } } }
14. House theft 2
class Solution { public int rob(int[] nums) { int n = nums.length; if (n == 1) { return nums[0]; }else if(n == 2) { return Math.max(nums[0], nums[1]); }else if(n == 3){ return Math.max(nums[0], Math.max(nums[1], nums[2])); }else{ int[][] f = new int[n][2]; f[0][0] = nums[0]; f[0][1] = 0; f[1][0] = nums[0]; f[1][1] = nums[1]; f[2][0] = nums[0]; f[2][1] = Math.max(nums[1], nums[2]); for(int i = 3; i < n; i++) { f[i][0] = Math.max(f[i - 1][0], f[i - 2][0]+ nums[i - 1]); f[i][1] = Math.max(f[i - 1][1], f[i - 2][1]+ nums[i]); } return Math.max(f[n - 1][0], f[n - 1][1]); } } }
15. Maximum profit of shares
class Solution { public int maxProfit(int[] prices) { int n = prices.length; if(n <= 1) { return 0; }else { int[] dp = new int[n]; dp[0] = 0; int tmp = prices[0]; for(int i = 1; i < n; i++) { if(tmp > prices[i]){ tmp = prices[i]; } if(prices[i] < prices[i - 1]){ dp[i] = dp[i - 1]; }else{ dp[i] = Math.max(prices[i] - tmp, dp[i - 1]); } } return dp[n - 1]; } } }