Skip to content

Commit cd5790d

Browse files
committed
20190116
1 parent a5a28fa commit cd5790d

File tree

7 files changed

+166
-5
lines changed

7 files changed

+166
-5
lines changed

code/lc121.java

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* 题意:股票买卖1次,最大利润
55
* 难度:Easy
66
* 分类:Arryas, Dynamic Programming
7+
* Tips:lc122
78
*/
89
public class lc121 {
910
public int maxProfit(int[] prices) {

code/lc122.java

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package code;
2+
/*
3+
* 122. Best Time to Buy and Sell Stock II
4+
* 题意:买卖股票最大利润,可以买多次
5+
* 难度:Easy
6+
* 分类:Array, Greedy
7+
* 思路:计算 prices[i] 与 prices[i-1] 的差值,把正数全加起来就行了
8+
* Tips:lc121, lc309
9+
*/
10+
public class lc122 {
11+
public int maxProfit(int[] prices) {
12+
if(prices.length<1) return 0;
13+
int res = 0;
14+
for (int i = 1; i < prices.length ; i++) {
15+
if(prices[i]-prices[i-1]>0)
16+
res += prices[i]-prices[i-1];
17+
}
18+
return res;
19+
}
20+
}

code/lc287.java

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package code;
2+
/*
3+
* 287. Find the Duplicate Number
4+
* 题意:n+1个数属于[1~n],找出重复的那个数
5+
* 难度:Medium
6+
* 分类:Array, Two Pointers, Binary Search
7+
* 思路:如果nums[i]不在对应位置,则和对应位置交换。如果对应位置上也为该数,说明这个数就是重复的数字。这个方法改变了数组。是错误的。
8+
* 另一种方法,把问题转换成有环链表,找环的起始节点。O(n) O(1) lc142
9+
* 二分查找,每次看一边数字的个数, O(nlog(n)) O(1)
10+
* Tips:剑指offer原题
11+
*/
12+
public class lc287 {
13+
public int findDuplicate(int[] nums) { //该方法修改了数组,是错误的,没看清题意
14+
for (int i = 0; i < nums.length ; i++) {
15+
if(nums[i]!=i+1){
16+
int temp = nums[nums[i]-1];
17+
if(temp==nums[i])
18+
return temp;
19+
nums[nums[i]-1] = nums[i];
20+
nums[i] = temp;
21+
i--;
22+
}
23+
}
24+
return -1;
25+
}
26+
27+
public int findDuplicate2(int[] nums) {
28+
int slow = nums[0];
29+
int fast = nums[nums[0]];
30+
while(slow!=fast){
31+
slow = nums[slow];
32+
fast = nums[nums[fast]];
33+
}
34+
fast = 0; // fast是0,不是nums[0]
35+
while(slow!=fast){
36+
slow = nums[slow];
37+
fast = nums[fast];
38+
}
39+
return slow;
40+
}
41+
}

code/lc300.java

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package code;
2+
/*
3+
* 300. Longest Increasing Subsequence
4+
* 题意:最长递增子数组,不一定是连续的
5+
* 难度:Medium
6+
* 分类:Binary Search, Dynamic Programming
7+
* 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。
8+
* Tips:经典题目,记一下
9+
*/
10+
import java.util.Arrays;
11+
12+
public class lc300 {
13+
public int lengthOfLIS(int[] nums) {
14+
if(nums.length<2)
15+
return nums.length;
16+
int[] dp = new int[nums.length]; //dp[i] 存储以nums[i]结尾的最大长度
17+
Arrays.fill(dp,1);
18+
int res = 1;
19+
for (int i = 1; i < nums.length ; i++) {
20+
for (int j = 0; j < i ; j++) {
21+
if(nums[i]>nums[j]){
22+
dp[i] = Math.max(dp[j]+1, dp[i]);
23+
}
24+
}
25+
res = Math.max(res, dp[i]);
26+
}
27+
return res;
28+
}
29+
30+
public int lengthOfLIS2(int[] nums) {
31+
if(nums.length<2)
32+
return nums.length;
33+
int size = 0; //size指dp中递增的长度。 dp[0~i] 表示了长度为 i+1 的递增子数组,且最后一个值是最小值
34+
int[] dp = new int[nums.length]; //dp存储递增的数组,之后更新这个数组。如果x>最后一个值,则插入到末尾,否则更新对应位置上的值为该值。
35+
for (int i = 0; i < nums.length ; i++) {
36+
int left = 0;
37+
int right = size;
38+
while(left!=right){ //得到要插入的位置
39+
int mid = (left+right)/2;
40+
if(dp[mid]<nums[i])
41+
left = mid+1;
42+
else
43+
right = mid;
44+
}
45+
dp[left] = nums[i];
46+
if(left==size) size++;
47+
}
48+
return size;
49+
}
50+
}

code/lc309.java

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package code;
2+
/*
3+
* 309. Best Time to Buy and Sell Stock with Cooldown
4+
* 题意:最佳时间买卖股票,有冷却期,如果前一天卖了,下一天就不能买
5+
* 难度:Medium
6+
* 分类:Dynamic Programming
7+
* 思路:状态DP,自己不会写。要分两种状态,手中有股票时最大收益,手中没股票时最大收益(包括冷冻期)。
8+
* buy[i] = max( buy[i-1], sell[i-2]-price[i] )
9+
* sell[i] = max( sell[i-1], buy[i-1]+price[i] )
10+
* 空间压缩以后时间是O(n),空间是O(1)
11+
* Tips:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75931/Easiest-JAVA-solution-with-explanations
12+
* lc122
13+
*/
14+
public class lc309 {
15+
public int maxProfit(int[] prices) {
16+
if(prices.length==0) return 0;
17+
int b1 = -prices[0];
18+
int s2=0, s1=0;
19+
int b = 0, s = 0;
20+
for (int i = 0; i < prices.length ; i++) {
21+
b = Math.max(b1, s2-prices[i]);
22+
s = Math.max(s1, b1+prices[i]);
23+
s2 = s1;
24+
s1 = s;
25+
b1 = b;
26+
}
27+
return Math.max(s,b);
28+
}
29+
}

code/lc312.java

+24-4
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
* 难度:Hard
66
* 分类:Divide and Conquer, Dynamic Programming
77
* 思路:假设第n个气球是最后一个被踩爆,则从第n个气球开始,数组可以分为无前后相关性的两块
8-
* Tips:太难了,弃疗了,不会写。直接粘答案。
8+
* 首尾补1,最小区间为3个数,maxCoins[1,4],则需遍历2,3两种情况, 1,4指的是边界
9+
* maxCoins[0][n - 1] = maxCoins[0][i - 1] + maxCoins[i + 1][n - 1] + nums[left] * nums[i] * nums[right]
10+
* left是左边界,right是右边界,不一定是相邻的
11+
* Tips:太难了,弃疗了,不会写。直接粘答案。区间dp。
912
*/
1013
public class lc312 {
1114
public static void main(String[] args) {
12-
System.out.println(maxCoins(new int[]{3,1,5,8}));
15+
System.out.println(maxCoins2(new int[]{3,1,5,8}));
1316
}
1417
public static int maxCoins(int[] iNums) {
1518
int[] nums = new int[iNums.length + 2];
1619
int n = 1;
1720
for (int x : iNums) if (x > 0) nums[n++] = x;
1821
nums[0] = nums[n++] = 1;
19-
20-
2122
int[][] memo = new int[n][n];
2223
int res = burst(memo, nums, 0, n - 1);
2324
return res;
@@ -34,4 +35,23 @@ public static int burst(int[][] memo, int[] nums, int left, int right) {
3435
return ans;
3536
}
3637

38+
public static int maxCoins2(int[] iNums) {
39+
int[] nums = new int[iNums.length + 2];
40+
int n = 1;
41+
for (int x : iNums) if (x > 0) nums[n++] = x;
42+
nums[0] = nums[n++] = 1;
43+
44+
45+
int[][] dp = new int[n][n];
46+
for (int k = 2; k < n; ++k)
47+
for (int left = 0; left < n - k; ++left) {
48+
int right = left + k;
49+
for (int i = left + 1; i < right; ++i)
50+
dp[left][right] = Math.max(dp[left][right],
51+
nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]);
52+
}
53+
54+
return dp[0][n - 1];
55+
}
56+
3757
}

code/lc437.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public static int dfs(TreeNode root, int sum) { //一条路径向下走
5151
if (root == null)
5252
return 0;
5353
if (root.val == sum)
54-
return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);
54+
return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);//不要直接返回1,因为可能后边节点,或节点和为0
5555
return dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);
5656
}
5757

0 commit comments

Comments
 (0)