8000 DP · rchen102/Leetcode-Notes@68e31cb · GitHub
[go: up one dir, main page]

Skip to content

Commit 68e31cb

Browse files
author
rchen102
committed
DP
1 parent 5662225 commit 68e31cb

10 files changed

+252
-101
lines changed

Java/leetcode 121.java

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,57 @@
1-
//Solution1: divide and conquer T: O(nlogn) S: O(logn)
1+
// Solution: dp 状态机模型 T: O(n) S: O(n)
22
class Solution {
33
public int maxProfit(int[] prices) {
4-
if(prices.length <= 1)
5-
return 0;
6-
int res = subMax(prices, 0, prices.length - 1);
7-
return res;
4+
if (prices == null || prices.length <= 1) return 0;
5+
int n = prices.length;
6+
int[][] dp = new int[n][2];
7+
dp[0][0] = 0;
8+
dp[0][1] = -prices[0];
9+
for (int i = 1; i < n; i++) {
10+
dp[i][1] = Math.max(dp[i-1][1], -prices[i]);
11+
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
12+
}
13+
return dp[n-1][0];
814
}
9-
10-
public int subMax(int[] prices, int start, int end) {
11-
if(start == end) return 0;
15+
}
16+
17+
// 状态压缩优化 T: O(n) S: O(1)
18+
class Solution {
19+
public int maxProfit(int[] prices) {
20+
if (prices == null || prices.length <= 1) return 0;
21+
int n = prices.length;
1222

13-
int mid = (start + end)/2;
14-
int tmp = getMax(prices, mid + 1, end) - getMin(prices, start, mid);
15-
if(tmp < 0) tmp = 0;
23+
int keep = 0;
24+
int buy = -prices[0];
1625

17-
int tmp2 = Math.max(subMax(prices, start, mid), subMax(prices, mid + 1, end));
18-
return Math.max(tmp, tmp2);
19-
}
20-
21-
//Get max in the array prices from index start to end
22-
public int getMax(int[] prices, int start, int end) {
23-
int max = prices[start];
24-
for(int i = start; i <= end; i++) {
25-
if(prices[i] > max)
26-
max = prices[i];
26+
for (int i = 1; i < n; i++) {
27+
keep = Math.max(keep, buy + prices[i]);
28+
buy = Math.max(buy, -prices[i]);
2729
}
28-
return max;
30+
return keep;
2931
}
30-
31-
//Get min in the array prices from index start to end
32-
public int getMin(int[] prices, int start, int end) {
33-
int min = prices[start];
34-
for(int i = start; i <= end; i++) {
35-
if(prices[i] < min)
36-
min = prices[i];
37-
}
38-
return min;
39-
}
40-
4132
}
4233

4334

44-
//Solution2: Kadane's Algorithm (dynamic programming) T: O(n) S: O(1)
35+
// Solution: dp 转换为求最大子数组和的问题 T: O(n) S: O(1)
4536
class Solution {
4637
public int maxProfit(int[] prices) {
47-
int maxCur = 0, maxSofar = 0;
48-
for(int i = 1; i < prices.length; i++) {
49-
maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]);
50-
maxSofar= Math.max(maxCur, maxSofar);
38+
if (prices == null || prices.length <= 1) return 0;
39+
int[] diff = new int[prices.length - 1];
40+
for (int i = 0; i < diff.length; i++) {
41+
diff[i] = prices[i+1] - prices[i];
5142
}
52-
return maxSofar;
43+
int res = findMaxSubarray(diff);
44+
return res > 0 ? res : 0;
45+
}
46+
47+
int findMaxSubarray(int[] arr) {
48+
int[] dp = new int[arr.length];
49+
dp[0] = arr[0];
50+
int max = dp[0];
51+
for (int i = 1; i < arr.length; i++) {
52+
dp[i] = Math.max(arr[i], dp[i-1] + arr[i]);
53+
max = Math.max(dp[i], max);
54+
}
55+
return max;
5356
}
5457
}

Java/leetcode 122.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
// Solution: 基本 dp T: O(n) S: O(n) (可以状态压缩至 O(1))
2+
class Solution {
3+
public int maxProfit(int[] prices) {
4+
if (prices == null || prices.length <= 1) return 0;
5+
int n = prices.length;
6+
int[][] dp = new int[n][2];
7+
// base cases
8+
dp[0][0] = 0;
9+
dp[0][1] = -prices[0];
10+
// dp
11+
for (int i = 1; i < n; i++) {
12+
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
13+
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
14+
}
15+
return dp[n-1][0];
16+
}
17+
}
18+
19+
120
//Solution1: T: O(n) S: O(1)
221
class Solution {
322
public int maxProfit(int[] prices) {

Java/leetcode 123.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Solution: 基本 dp T: O(2n) S: O(nk2)
2+
class Solution {
3+
public int maxProfit(int[] prices) {
4+
if (prices == null || prices.length <= 1) return 0;
5+
int n = prices.length;
6+
int k_max = 2;
7+
int[][][] dp = new int[n][k_max+1][2];
8+
// base case
9+
for (int k = 0; k <= k_max; k++) {
10+
dp[0][k][0] = Integer.MIN_VALUE >> 1;
11+
dp[0][k][1] = Integer.MIN_VALUE >> 1;
12+
}
13+
dp[0][0][0] = 0;
14+
dp[0][1][1] = -prices[0];
15+
16+
// dp
17+
int res = 0;
18+
for (int i = 1; i < n; i++) {
19+
for (int k = 1; k <= k_max; k++) {
20+
dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
21+
dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
22+
if (i == n-1) {
23+
res = Math.max(res, dp[i][k][0]);
24+
}
25+
}
26+
}
27+
return res;
28+
}
29+
}

Java/leetcode 188.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class Solution {
2+
public int maxProfit(int k, int[] prices) {
3+
if (prices == null || prices.length <= 1 || k == 0) return 0;
4+
int n = prices.length;
5+
if (k > n/2) {
6+
return maxProfitNoLimit(prices);
7+
}
8+
int k_max = k;
9+
int[][][] dp = new int[n][k_max+1][2];
10+
// base case
11+
for (k = 0; k <= k_max; k++) {
12+
dp[0][k][0] = Integer.MIN_VALUE >> 1;
13+
dp[0][k][1] = Integer.MIN_VALUE >> 1;
14+
}
15+
dp[0][0][0] = 0;
16+
dp[0][1][1] = -prices[0];
17+
18+
// dp
19+
int res = 0;
20+
for (int i = 1; i < n; i++) {
21+
for (k = 1; k <= k_max; k++) {
22+
dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
23+
dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
24+
if (i == n-1) {
25+
res = Math.max(res, dp[i][k][0]);
26+
}
27+
}
28+
}
29+
return res;
30+
}
31+
32+
public int maxProfitNoLimit(int[] prices) {
33+
if (prices == null || prices.length <= 1) return 0;
34+
int n = prices.length;
35+
int[][] dp = new int[n][2];
36+
// base cases
37+
dp[0][0] = 0;
38+
dp[0][1] = -prices[0];
39+
// dp
40+
for (int i = 1; i < n; i++) {
41+
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
42+
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
43+
}
44+
return dp[n-1][0];
45+
}
46+
}

Java/leetcode 198.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
//Own solution: dynamic programming T: O(n) S: O(n)
1+
// Solution: 基本dp T: O(n) S: O(n)
22
class Solution {
33
public int rob(int[] nums) {
4-
if(nums.length < 1)
5-
return 0;
6-
7-
int[] res = new int[nums.length];
8-
res[0] = nums[0];
9-
if(nums.length < 2)
10-
return res[0];
11-
12-
res[1] = Math.max(nums[0], nums[1]);
13-
for(int i = 2; i < nums.length; i++) {
14-
res[i] = Math.max(res[i-1], res[i-2] + nums[i]);
4+
if (nums == null || nums.length == 0) return 0;
5+
int n = nums.length;
6+
int[] dp = new int[n+1];
7+
// base cases
8+
dp[n] = 0;
9+
dp[n-1] = nums[n-1];
10+
// dp
11+
for (int i = n-2; i >= 0; i--) {
12+
dp[i] = Math.max(dp[i+1], nums[i] + dp[i+2]);
1513
}
16-
return res[nums.length - 1];
14+
return dp[0];
1715
}
1816
}
1917

20-
//More simplified version T: O(n) S: O(1)
18+
// 状态压缩 T: O(n) S: O(1)
2119
class Solution {
2220
public int rob(int[] nums) {
2321
int preMax = 0, curMax = 0;

Java/leetcode 213.java

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,20 @@
1-
//Own solution: 2 rob1 T: O(n) S: O(n)
1+
// Solution: 基本 dp + 状态压缩 T: O(n) S: O(1)
22
class Solution {
33
public int rob(int[] nums) {
4-
int len = nums.length;
5-
if(len < 1) return 0;
6-
else if(len < 2) return nums[0];
7-
else if(len < 3) return Math.max(nums[0], nums[1]);
4+
if (nums == null || nums.length == 0) return 0;
5+
if (nums.length == 1) return nums[0];
6+
return Math.max(robRange(nums, 0, nums.length - 2), robRange(nums, 1, nums.length-1));
87

9-
int[] tmp = new int[len - 1];
10-
for(int i = 0; i < len - 1; i++) {
11-
tmp[i] = nums[i];
12-
}
13-
int m1 = maxMoney(tmp);
14-
15-
int[] tmp2 = new int[len - 3];
16-
for(int i = 1; i < len - 2; i++) {
17-
tmp2[i-1] = nums[i];
18-
}
19-
int m2 = maxMoney(tmp2) + nums[len-1];
20-
return Math.max(m1, m2);
21-
}
22-
23-
private int maxMoney(int[] nums) {
24-
if(nums.length < 1) return 0;
25-
26-
int[] res = new int[nums.length];
27-
res[0] = nums[0];
28-
if(nums.length < 2)
29-
return res[0];
30-
31-
res[1] = Math.max(nums[0], nums[1]);
32-
for(int i = 2; i < nums.length; i++) {
33-
res[i] = Math.max(res[i-1], res[i-2] + nums[i]);
34-
}
35-
return res[nums.length - 1];
36-
}
37-
}
38-
39-
//More simplified version T: O(n) S: O(1)
40-
class Solution {
41-
public int rob(int[] nums) {
42-
int len = nums.length;
43-
if(len == 1) return nums[0];
44-
return Math.max(maxMoney(nums, 0, len - 2), maxMoney(nums, 1, len - 1));
458
}
469

47-
private int maxMoney(int[] nums, int start, int end) {
48-
int preMax = 0, curMax = 0;
49-
for(int j = start; j <= end; j++) {
50-
int t = curMax;
51-
curMax = Math.max(preMax+nums[j], curMax);
52-
preMax = t;
10+
public int robRange(int[] nums, int lo, int hi) {
11+
int prev = 0;
12+
int cur = nums[hi];
13+
for (int i = hi-1; i >= lo; i--) {
14+
int tmp = cur;
15+
cur = Math.max(cur, nums[i] + prev);
16+
prev = tmp;
5317
}
54-
return curMax;
18+
return cur;
5519
}
5620
}

Java/leetcode 309.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Solution: 基本 dp T: O(n) S: O(n) (可以状态压缩优化 S:O(1))
2+
class Solution {
3+
public int maxProfit(int[] prices) {
4+
if (prices == null || prices.length <= 1) return 0;
5+
int n = prices.length;
6+
int[][] dp = new int[n][2];
7+
// base
8+
dp[0][0] = 0;
9+
dp[0][1] = -prices[0];
10+
11+
for (int i = 1; i < n; i++) {
12+
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
13+
if (i >= 2) {
14+
dp[i][1] = Math.max(dp[i-1][1], dp[i-2][0] - prices[i]);
15+
} else {
16+
// dp[-1][] = 0,交易还未开始,该状态不可能存在
17+
dp[i][1] = Math.max(dp[i-1][1], 0 - prices[i]);
18+
}
19+
}
20+
return dp[n-1][0];
21+
}
22+
}

Java/leetcode 337.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Solution: 基本 dp T:O(n) S: O(n)
2+
class Solution {
3+
public int rob(TreeNode root) {
4+
int[] dp = dp(root);
5+
return Math.max(dp[0], dp[1]);
6+
}
7+
8+
// dp[0]: 代表选择不抢当前这个房子
9+
// dp[1]: 代表抢当前这个房子的结果
10+
public int[] dp(TreeNode root) {
11+
int[] dp = new int[2];
12+
if (root == null) return dp;
13+
int[] left = dp(root.left);
14+
int[] right = dp(root.right);
15+
// 不抢,则left 和 right 可抢可不抢
16+
dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
17+
// 抢,left 和 right 都不能抢
18+
dp[1] = root.val + left[0] + right[0];
19+
return dp;
20+
}
21+
}

Java/leetcode 714.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Solution: 基本 dp T: O(n) S: O(n) (状态压缩可优化 O(1))
2+
class Solution {
3+
public int maxProfit(int[] prices, int fee) {
4+
if (prices == null || prices.length <= 1) return 0;
5+
int n = prices.length;
6+
int[][] dp = new int[n][2];
7+
// base case
8+
dp[0][0] = 0;
9+
dp[0][1] = -prices[0];
10+
for (int i = 1; i < n; i++) {
11+
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i] - fee);
12+
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
13+
}
14+
return dp[n-1][0];
15+
}
16+
}

0 commit comments

Comments
 (0)
0