auto commit

This commit is contained in:
CyC2018 2018-03-28 16:55:33 +08:00
parent 90540c8bb8
commit d38b1c6ecd
2 changed files with 62 additions and 34 deletions

View File

@ -1890,12 +1890,12 @@ public int lengthOfLIS(int[] nums) {
} }
``` ```
以上解法的时间复杂度为 O(n<sup>2</sup>) ,可以使用二分查找使得时间复杂度降低为 O(nlog<sub>n</sub>)。定义一个 tails 数组,其中 tails[i] 存储长度为 i + 1 的最长递增子序列的最后一个元素,例如对于数组 [4,5,6,3],有 以上解法的时间复杂度为 O(n<sup>2</sup>) ,可以使用二分查找使得时间复杂度降低为 O(nlogn)。定义一个 tails 数组,其中 tails[i] 存储长度为 i + 1 的最长递增子序列的最后一个元素,例如对于数组 [4,5,6,3],有
```html ```html
len = 1 : [4], [5], [6], [3] => tails[0] = 3 len = 1 : [4], [5], [6], [3] => tails[0] = 3
len = 2 : [4, 5], [5, 6] => tails[1] = 5 len = 2 : [4, 5], [5, 6] => tails[1] = 5
len = 3 : [4, 5, 6] => tails[2] = 6 len = 3 : [4, 5, 6] => tails[2] = 6
``` ```
对于一个元素 x如果它大于 tails 数组所有的值,那么把它添加到 tails 后面;如果 tails[i-1] < x <= tails[i]那么更新 tails[i] = x 对于一个元素 x如果它大于 tails 数组所有的值,那么把它添加到 tails 后面;如果 tails[i-1] < x <= tails[i]那么更新 tails[i] = x
@ -1907,22 +1907,22 @@ public int lengthOfLIS(int[] nums) {
int n = nums.length; int n = nums.length;
int[] tails = new int[n]; int[] tails = new int[n];
int size = 0; int size = 0;
for(int i = 0; i < n; i++){ for (int i = 0; i < n; i++) {
int idx = binarySearch(tails, 0, size, nums[i]); int index = binarySearch(tails, 0, size, nums[i]);
tails[idx] = nums[i]; tails[index] = nums[i];
if(idx == size) size++; if (index == size) size++;
} }
return size; return size;
} }
private int binarySearch(int[] nums, int sIdx, int eIdx, int key){ private int binarySearch(int[] nums, int first, int last, int key) {
while(sIdx < eIdx){ while (first < last) {
int mIdx = sIdx + (eIdx - sIdx) / 2; int mid = first + (last - first) / 2;
if(nums[mIdx] == key) return mIdx; if (nums[mid] == key) return mid;
else if(nums[mIdx] > key) eIdx = mIdx; else if (nums[mid] > key) last = mid;
else sIdx = mIdx + 1; else first = mid + 1;
} }
return sIdx; return first;
} }
``` ```
@ -1930,6 +1930,19 @@ private int binarySearch(int[] nums, int sIdx, int eIdx, int key){
[Leetcode : 376. Wiggle Subsequence (Medium)](https://leetcode.com/problems/wiggle-subsequence/description/) [Leetcode : 376. Wiggle Subsequence (Medium)](https://leetcode.com/problems/wiggle-subsequence/description/)
```html
Input: [1,7,4,9,2,5]
Output: 6
The entire sequence is a wiggle sequence.
Input: [1,17,5,10,13,15,10,5,16,8]
Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
Input: [1,2,3,4,5,6,7,8,9]
Output: 2
```
要求:使用 O(n) 时间复杂度求解。 要求:使用 O(n) 时间复杂度求解。
使用两个状态 up 和 down。 使用两个状态 up 和 down。
@ -2008,7 +2021,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
for (int j = W - 1; j >= weights[i]; j--) { for (int j = W - 1; j >= weights[i]; j--) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i]] + values[i]); dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i]] + values[i]);
} }
for (int j = weights[i - 1] - 1; j >= 0; j--) { for (int j = weights[i] - 1; j >= 0; j--) {
dp[i][j] = dp[i - 1][j]; dp[i][j] = dp[i - 1][j];
} }
} }
@ -2048,6 +2061,14 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
[Leetcode : 416. Partition Equal Subset Sum (Medium)](https://leetcode.com/problems/partition-equal-subset-sum/description/) [Leetcode : 416. Partition Equal Subset Sum (Medium)](https://leetcode.com/problems/partition-equal-subset-sum/description/)
```html
Input: [1, 5, 11, 5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
```
可以看成一个背包大小为 sum/2 的 0-1 背包问题,但是也有不同的地方,这里没有价值属性,并且背包必须被填满。 可以看成一个背包大小为 sum/2 的 0-1 背包问题,但是也有不同的地方,这里没有价值属性,并且背包必须被填满。
以下实现使用了空间优化。 以下实现使用了空间优化。
@ -2063,16 +2084,16 @@ public boolean canPartition(int[] nums) {
} }
int W = sum / 2; int W = sum / 2;
boolean[] dp = new boolean[W + 1]; boolean[] dp = new boolean[W + 1];
int n = nums.length; for (int i = 0; i <= W; i++) {
for(int i = 0; i <= W; i++) { if (nums[0] == i) {
if(nums[0] == i) dp[i] = true; dp[i] = true;
}
} }
for(int i = 1; i < n; i++) { for (int i = 1; i < nums.length; i++) {
for(int j = W; j >= nums[i]; j--) { for (int j = W; j >= nums[i]; j--) {
dp[j] = dp[j] || dp[j - nums[i]]; dp[j] = dp[j] || dp[j - nums[i]];
} }
} }
return dp[W]; return dp[W];
} }
``` ```
@ -2094,8 +2115,7 @@ public boolean wordBreak(String s, List<String> wordDict) {
dp[0] = true; dp[0] = true;
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
for (String word : wordDict) { for (String word : wordDict) {
if (word.length() <= i if (word.length() <= i && word.equals(s.substring(i - word.length(), i))) {
&& word.equals(s.substring(i - word.length(), i))) {
dp[i] = dp[i] || dp[i - word.length()]; dp[i] = dp[i] || dp[i - word.length()];
} }
} }
@ -2174,9 +2194,8 @@ Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3
```java ```java
public int findMaxForm(String[] strs, int m, int n) { public int findMaxForm(String[] strs, int m, int n) {
if (strs == null || strs.length == 0) return 0; if (strs == null || strs.length == 0) return 0;
int l = strs.length;
int[][] dp = new int[m + 1][n + 1]; int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i < l; i++) { for (int i = 0; i < strs.length; i++) {
String s = strs[i]; String s = strs[i];
int ones = 0, zeros = 0; int ones = 0, zeros = 0;
for (char c : s.toCharArray()) { for (char c : s.toCharArray()) {
@ -2185,9 +2204,7 @@ public int findMaxForm(String[] strs, int m, int n) {
} }
for (int j = m; j >= zeros; j--) { for (int j = m; j >= zeros; j--) {
for (int k = n; k >= ones; k--) { for (int k = n; k >= ones; k--) {
if (zeros <= j && ones <= k) { dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1);
dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1);
}
} }
} }
} }
@ -2199,20 +2216,30 @@ public int findMaxForm(String[] strs, int m, int n) {
[Leetcode : 322. Coin Change (Medium)](https://leetcode.com/problems/coin-change/description/) [Leetcode : 322. Coin Change (Medium)](https://leetcode.com/problems/coin-change/description/)
```html
Example 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)
Example 2:
coins = [2], amount = 3
return -1.
```
题目描述:给一些面额的硬币,要求用这些硬币来组成给定面额的钱数,并且使得硬币数量最少。硬币可以重复使用。 题目描述:给一些面额的硬币,要求用这些硬币来组成给定面额的钱数,并且使得硬币数量最少。硬币可以重复使用。
这是一个完全背包问题,完全背包问题和 0-1 背包问题在实现上唯一的不同是,第二层循环是从 0 开始的,而不是从尾部开始。 这是一个完全背包问题,完全背包问题和 0-1 背包问题在实现上唯一的不同是,第二层循环是从 0 开始的,而不是从尾部开始。
```java ```java
public int coinChange(int[] coins, int amount) { public int coinChange(int[] coins, int amount) {
if (coins == null || coins.length == 0) return 0;
Arrays.sort(coins);
int[] dp = new int[amount + 1]; int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1); Arrays.fill(dp, amount + 1);
dp[0] = 0; dp[0] = 0;
for (int i = 1; i <= amount; i++) { for (int i = 1; i <= amount; i++) {
for (int j = 0; j < coins.length; j++) { for (int j = 0; j < coins.length && coins[j] <= i; j++) {
if (coins[j] <= i) { dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
}
} }
} }
return dp[amount] > amount ? -1 : dp[amount]; return dp[amount] > amount ? -1 : dp[amount];
@ -2243,11 +2270,12 @@ Therefore the output is 7.
```java ```java
public int combinationSum4(int[] nums, int target) { public int combinationSum4(int[] nums, int target) {
if (nums == null || nums.length == 0) return 0;
int[] dp = new int[target + 1]; int[] dp = new int[target + 1];
dp[0] = 1; dp[0] = 1;
for (int i = 1; i <= target; i++) { for (int i = 1; i <= target; i++) {
for (int j = 0; j < nums.length; j++) { for (int j = 0; j < nums.length; j++) {
if(nums[j] <= i) { if (nums[j] <= i) {
dp[i] += dp[i - nums[j]]; dp[i] += dp[i - nums[j]];
} }
} }
@ -2285,7 +2313,7 @@ dp[i, j] = max(dp[i, j-1], prices[j] - prices[jj] + dp[i-1, jj]) { jj in range o
```java ```java
public int maxProfit(int k, int[] prices) { public int maxProfit(int k, int[] prices) {
int n = prices.length; int n = prices.length;
if (k >= n/2) { if (k >= n/2) { // 这种情况下该问题退化为普通的股票交易问题
int maxPro = 0; int maxPro = 0;
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
if (prices[i] > prices[i-1]) if (prices[i] > prices[i-1])

View File

@ -975,7 +975,7 @@ public class BinarySearchST<Key extends Comparable<Key>, Value> {
<div align="center"> <img src="../pics//1c012d74-6b9d-4f25-a016-7ad4f1f1521898780376.png" width="400"/> </div><br> <div align="center"> <img src="../pics//1c012d74-6b9d-4f25-a016-7ad4f1f1521898780376.png" width="400"/> </div><br>
BST 有一个重要性质,就是它的序遍历结果递增排序。 BST 有一个重要性质,就是它的序遍历结果递增排序。
<div align="center"> <img src="../pics//5c0bb285-b917-446b-84a2-9810ee41521898714517.png" width="300"/> </div><br> <div align="center"> <img src="../pics//5c0bb285-b917-446b-84a2-9810ee41521898714517.png" width="300"/> </div><br>