auto commit

This commit is contained in:
CyC2018 2018-03-28 16:03:28 +08:00
parent 76933f018a
commit 90540c8bb8

View File

@ -13,14 +13,14 @@
* [Backtracking](#backtracking)
* [分治](#分治)
* [动态规划](#动态规划)
* [分割整数](#分割整数)
* [矩阵路径](#矩阵路径)
* [斐波那契数列](#斐波那契数列)
* [最长递增子序列](#最长递增子序列)
* [最长公共子系列](#最长公共子系列)
* [0-1 背包](#0-1-背包)
* [数组区间](#数组区间)
* [字符串编辑](#字符串编辑)
* [分割整数](#分割整数)
* [矩阵路径](#矩阵路径)
* [其它问题](#其它问题)
* [数学](#数学)
* [素数](#素数)
@ -1719,130 +1719,6 @@ public List<Integer> diffWaysToCompute(String input) {
递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存了子问题的解。
### 分割整数
**分割整数的最大乘积**
[Leetcode : 343. Integer Break (Medim)](https://leetcode.com/problems/integer-break/description/)
题目描述For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).
```java
public int integerBreak(int n) {
int[] dp = new int[n + 1];
dp[1] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= i - 1; j++) {
dp[i] = Math.max(dp[i], Math.max(j * dp[i - j], j * (i - j)));
}
}
return dp[n];
}
```
**按平方数来分割整数**
[Leetcode : 279. Perfect Squares(Medium)](https://leetcode.com/problems/perfect-squares/description/)
题目描述For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.
```java
public int numSquares(int n) {
List<Integer> squareList = generateSquareList(n);
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
int max = Integer.MAX_VALUE;
for (int square : squareList) {
if (square > i) break;
max = Math.min(max, dp[i - square] + 1);
}
dp[i] = max;
}
return dp[n];
}
private List<Integer> generateSquareList(int n) {
List<Integer> squareList = new ArrayList<>();
int diff = 3;
int square = 1;
while (square <= n) {
squareList.add(square);
square += diff;
diff += 2;
}
return squareList;
}
```
**分割整数构成字母字符串**
[Leetcode : 91. Decode Ways (Medium)](https://leetcode.com/problems/decode-ways/description/)
题目描述Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).
```java
public int numDecodings(String s) {
if(s == null || s.length() == 0) return 0;
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;
for(int i = 2; i <= n; i++) {
int one = Integer.valueOf(s.substring(i - 1, i));
if(one != 0) dp[i] += dp[i - 1];
if(s.charAt(i - 2) == '0') continue;
int two = Integer.valueOf(s.substring(i - 2, i));
if(two <= 26) dp[i] += dp[i - 2];
}
return dp[n];
}
```
### 矩阵路径
**矩阵的总路径数**
[Leetcode : 62. Unique Paths (Medium)](https://leetcode.com/problems/unique-paths/description/)
题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向右或者向下移动。
<div align="center"> <img src="../pics//7c98e1b6-c446-4cde-8513-5c11b9f52aea.jpg"/> </div><br>
```java
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(i == 0) dp[j] = 1;
else if(j != 0) dp[j] = dp[j] + dp[j - 1];
}
}
return dp[n - 1];
}
```
**矩阵的最小路径和**
[Leetcode : 64. Minimum Path Sum (Medium)](https://leetcode.com/problems/minimum-path-sum/description/)
题目描述:求从矩阵的左上角到右下角的最小路径和,每次只能向左和向下移动。
```java
public int minPathSum(int[][] grid) {
if(grid.length == 0 || grid[0].length == 0) return 0;
int m = grid.length, n = grid[0].length;
int[] dp = new int[n];
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(j == 0) dp[0] = dp[0] + grid[i][0];
else if(i == 0) dp[j] = dp[j - 1] + grid[0][j];
else dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
}
}
return dp[n - 1];
}
```
### 斐波那契数列
**爬楼梯**
@ -1863,7 +1739,6 @@ dp[N] 即为所求。
public int climbStairs(int n) {
if(n == 1) return 1;
if(n == 2) return 2;
// 前一个楼梯、后一个楼梯
int pre1 = 2, pre2 = 1;
for(int i = 2; i < n; i++){
int cur = pre1 + pre2;
@ -1937,31 +1812,32 @@ public int rob(int[] nums) {
[Leetcode : 213. House Robber II (Medium)](https://leetcode.com/problems/house-robber-ii/description/)
```java
private int[] dp;
public int rob(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int n = nums.length;
if (n == 1) return nums[0];
dp = new int[n];
return Math.max(rob(nums, 0, n - 2), rob(nums, 1, n - 1));
}
private int rob(int[] nums, int s, int e) {
int n = nums.length;
if(e - s == 0) return nums[s];
if(e - s == 1) return Math.max(nums[s], nums[s + 1]);
int[] dp = new int[n];
dp[s] = nums[s];
dp[s + 1] = nums[s + 1];
dp[s + 2] = nums[s] + nums[s + 2];
for (int i = s + 3; i <= e; i++) {
private int rob(int[] nums, int first, int last) {
if (last - first == 0) return nums[first];
if (last - first == 1) return Math.max(nums[first], nums[first + 1]);
dp[first] = nums[first];
dp[first + 1] = nums[first + 1];
dp[first + 2] = nums[first] + nums[first + 2];
for (int i = first + 3; i <= last; i++) {
dp[i] = Math.max(dp[i - 2], dp[i - 3]) + nums[i];
}
return Math.max(dp[e], dp[e - 1]);
return Math.max(dp[last], dp[last - 1]);
}
```
**信件错排**
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式数量。
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式数量。
定义一个数组 dp 存储错误方式数量dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况:
@ -2545,6 +2421,137 @@ public int minDistance(String word1, String word2) {
[Leetcode : 72. Edit Distance (Hard)](https://leetcode.com/problems/edit-distance/description/)
### 分割整数
**分割整数的最大乘积**
[Leetcode : 343. Integer Break (Medim)](https://leetcode.com/problems/integer-break/description/)
题目描述For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).
```java
public int integerBreak(int n) {
int[] dp = new int[n + 1];
dp[1] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= i - 1; j++) {
dp[i] = Math.max(dp[i], Math.max(j * dp[i - j], j * (i - j)));
}
}
return dp[n];
}
```
**按平方数来分割整数**
[Leetcode : 279. Perfect Squares(Medium)](https://leetcode.com/problems/perfect-squares/description/)
题目描述For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.
```java
public int numSquares(int n) {
List<Integer> squareList = generateSquareList(n);
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
int max = Integer.MAX_VALUE;
for (int square : squareList) {
if (square > i) break;
max = Math.min(max, dp[i - square] + 1);
}
dp[i] = max;
}
return dp[n];
}
private List<Integer> generateSquareList(int n) {
List<Integer> squareList = new ArrayList<>();
int diff = 3;
int square = 1;
while (square <= n) {
squareList.add(square);
square += diff;
diff += 2;
}
return squareList;
}
```
**分割整数构成字母字符串**
[Leetcode : 91. Decode Ways (Medium)](https://leetcode.com/problems/decode-ways/description/)
题目描述Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).
```java
public int numDecodings(String s) {
if(s == null || s.length() == 0) return 0;
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;
for(int i = 2; i <= n; i++) {
int one = Integer.valueOf(s.substring(i - 1, i));
if(one != 0) dp[i] += dp[i - 1];
if(s.charAt(i - 2) == '0') continue;
int two = Integer.valueOf(s.substring(i - 2, i));
if(two <= 26) dp[i] += dp[i - 2];
}
return dp[n];
}
```
### 矩阵路径
**矩阵的总路径数**
[Leetcode : 62. Unique Paths (Medium)](https://leetcode.com/problems/unique-paths/description/)
题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向右或者向下移动。
<div align="center"> <img src="../pics//7c98e1b6-c446-4cde-8513-5c11b9f52aea.jpg"/> </div><br>
```java
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[j] = dp[j] + dp[j - 1];
}
}
return dp[n - 1];
}
```
**矩阵的最小路径和**
[Leetcode : 64. Minimum Path Sum (Medium)](https://leetcode.com/problems/minimum-path-sum/description/)
```html
[[1,3,1],
[1,5,1],
[4,2,1]]
Given the above grid map, return 7. Because the path 1→3→1→1→1 minimizes the sum.
```
题目描述:求从矩阵的左上角到右下角的最小路径和,每次只能向左和向下移动。
```java
public int minPathSum(int[][] grid) {
if (grid.length == 0 || grid[0].length == 0) return 0;
int m = grid.length, n = grid[0].length;
int[] dp = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j == 0) dp[0] = dp[0] + grid[i][0]; // 只能从上侧走到该位置
else if (i == 0) dp[j] = dp[j - 1] + grid[0][j]; // 只能从右侧走到该位置
else dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
}
}
return dp[n - 1];
}
```
### 其它问题
**需要冷却期的股票交易**