Skip to content

Commit 88da6b2

Browse files
Merge pull request #21 from daikaixian/master
4th homework
2 parents 19b5c59 + b7c99cb commit 88da6b2

File tree

9 files changed

+345
-0
lines changed

9 files changed

+345
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
class Solution {
3+
public int minPathSum(int[][] grid) {
4+
// 比较典型的dp, 找最小。
5+
// 应该是需要dfs?全盘dfs吗?好像是需要额。
6+
// 方式一是dfs,全盘遍历,记录最小值。
7+
// 方式二是dp. 从最底层元素往回找,更新每个元素的值。最小值则是对于起点元素,求出其右边的值和下边的值,哪个更小,然后加上自己,就是返回值。
8+
// dp的优势在于,减少了重复计算。 其实可以从头开始遍历, O(m*n)
9+
10+
11+
if(grid == null || grid.length == 0) {
12+
return -1; //应该是不会出现这种情况。
13+
}
14+
15+
int m = grid.length;
16+
int n = grid[0].length;
17+
18+
int [][] memo = new int [m][n];
19+
memo[m-1][n-1] = grid[m-1][n-1];
20+
21+
for (int i=m-1; i>= 0;i--) {
22+
for(int j=n-1;j>=0; j--) {
23+
if (j == n-1 && i == m-1) {
24+
continue;
25+
}
26+
memo[i][j] = getMin(grid, memo, i, j);
27+
}
28+
}
29+
30+
return memo[0][0];
31+
32+
}
33+
34+
private int getMin(int[][] grid,int[][] memo, int i, int j) {
35+
36+
37+
int ret = 0;
38+
if(i<grid.length-1&&j<grid[0].length -1) {
39+
ret = Math.min(memo[i+1][j],memo[i][j+1]) + grid[i][j];
40+
} else if (i<grid.length - 1 && j == grid[0].length-1) { //在最右边一列
41+
ret = memo[i+1][j] + grid[i][j];
42+
} else { //在最下面一行
43+
ret = memo[i][j+1] + grid[i][j];
44+
}
45+
46+
return ret;
47+
48+
49+
}
50+
51+
52+
53+
54+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
class Solution {
3+
// 这个算dp?
4+
public int maxProfit(int[] prices) {
5+
6+
if(prices == null || prices.length == 0) {
7+
return 0;
8+
}
9+
10+
int min = prices[0];
11+
int ret = 0;
12+
13+
for(int i=1; i<prices.length; i++) {
14+
15+
ret = Math.max(ret, prices[i] - min);
16+
min = Math.min(min, prices[i]);
17+
18+
}
19+
return ret;
20+
21+
}
22+
}

4th/homework_3/id_80/Stock2.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
class Solution {
3+
public int maxProfit(int[] prices) {
4+
// 没思路 啊?
5+
// 多次买入卖出。
6+
7+
// 只能dp吧?贪心估计算出来不是全局最优。
8+
//可以考虑,以每个节点为买入点,一直遍历到结尾,求出其所有可能的卖出点。但是这样是单次的吧,第二次买入点了?
9+
// 想不出来,看答案了。
10+
11+
// 艹尼玛!!!看了答案,好简单啊!!!
12+
13+
int total = 0;
14+
for (int i=0; i< prices.length-1; i++) {
15+
if (prices[i+1]>prices[i]) total += prices[i+1]-prices[i];
16+
}
17+
18+
return total;
19+
}
20+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
3+
class Solution {
4+
5+
6+
public int climbStairs(int n) {
7+
8+
// 一共n阶台阶
9+
// 每次一阶或者两阶
10+
// 共有几种方式完成攀登。
11+
12+
// 感觉和生成括号有点类似。
13+
// dfs? --> 超时了。
14+
// 二分搜索后相乘? --》应该是这个思路。 --->操蛋了。
15+
16+
//根据test发现,其实是个fib数列。我曹了。 --> 原理是,到达最后一个节点的方法,只有两种,即从倒数第二个到达,和从倒数第三个到达
17+
18+
if (n ==1) {
19+
return 1;
20+
} if(n == 2) {
21+
return 2;
22+
}
23+
int [] result = new int [n];
24+
result[0] =1;
25+
result[1]=2;
26+
27+
for (int i=2; i<n ; i++) {
28+
result[i] = result[i-1]+result[i-2];
29+
}
30+
return result[n-1];
31+
32+
}
33+
34+
35+
36+
37+
}

4th/homework_5/id_80/Robber.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
class Solution {
3+
public int rob(int[] nums) {
4+
5+
// 题意是还算简单易懂,但是怎么个做法了。
6+
7+
// 求max。
8+
9+
// 直接遍历,按单双数是有问题的。
10+
11+
//其实是不是只有四种情况,以1或2为起点,然后3/4和 4/5变成了可以选择的选项?
12+
//求出最大值,一直更新最大值即可。
13+
//这个算dfs吧
14+
15+
// 那dp了?想不出来dp有什么招啊! dfs肯定又超时。
16+
17+
//最后两家肯定抢一家。
18+
// 好了,只想出了low的dfs.
19+
if(nums == null || nums.length ==0) {
20+
return 0;
21+
}
22+
23+
// 有个关系在这。
24+
for(int i=0; i<nums.length; i++) {
25+
if (i==0) {
26+
continue;
27+
}
28+
if(i ==1) {
29+
nums[1] = Math.max(nums[0], nums[1]);
30+
continue;
31+
}
32+
nums[i] = Math.max(nums[i-2] +nums[i], nums[i-1]);
33+
}
34+
35+
return nums[nums.length -1];
36+
}
37+
}

4th/homework_6/id_80/Triangle.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
class Solution {
3+
4+
public int minimumTotal(List<List<Integer>> triangle) {
5+
6+
// dp
7+
// 从下至上,修改没一个值。
8+
if(triangle == null ||triangle.size() == 0) {
9+
return 0;
10+
}
11+
12+
int len = triangle.size();
13+
14+
for(int i=len - 2; i>=0; i--) {
15+
List<Integer> list = triangle.get(i);
16+
List<Integer> list2 = triangle.get(i+1);
17+
18+
for(int j =0;j< list.size(); j++) {
19+
list.set(j, Math.min(list2.get(j), list2.get(j+1)) + list.get(j));
20+
}
21+
22+
}
23+
return triangle.get(0).get(0);
24+
25+
26+
27+
}
28+
29+
}
30+
31+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
class Solution {
3+
public int maxProduct(int[] nums) {
4+
5+
//1. 求乘积. 0也可以考虑进去的,关键要考虑负数的问题。 --》 忘了。还要是相邻的。
6+
//2. dfs怎么搞?
7+
// dp又怎么搞? 如何找到要递推的东西?
8+
9+
//想不出来。 负数的位置让我找不出任何规律。
10+
11+
//看答案。
12+
13+
14+
int r = nums[0];
15+
int n = nums.length;
16+
// imax/imin stores the max/min product of
17+
// subarray that ends with the current number A[i]
18+
for (int i = 1, imax = r, imin = r; i < n; i++) {
19+
// multiplied by a negative makes big number smaller, small number bigger
20+
// so we redefine the extremums by swapping them
21+
if (nums[i] < 0) {
22+
int temp = imin;
23+
imin = imax;
24+
imax = temp;
25+
}
26+
27+
28+
// max/min product for the current number is either the current number itself
29+
// or the max/min by the previous number times the current one
30+
imax = Math.max(nums[i], imax * nums[i]);
31+
imin = Math.min(nums[i], imin * nums[i]);
32+
33+
// the newly computed max value is a candidate for our global result
34+
r = Math.max(r, imax);
35+
}
36+
return r;
37+
38+
39+
40+
41+
}
42+
}

4th/homework_8/id_80/Robber2.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
class Solution {
3+
public int rob(int[] nums) {
4+
5+
// 直接拿1 的答案过来套, 因为有了环,所以要么终点往前移一个,要么起点往后移一个。
6+
//
7+
8+
if(nums == null || nums.length ==0) {
9+
return 0;
10+
}
11+
if(nums.length == 1){
12+
return nums[0];
13+
}
14+
if(nums.length == 2) {
15+
return Math.max(nums[0], nums[1]);
16+
}
17+
18+
19+
20+
int max[] = new int[nums.length-1];
21+
int max2[] = new int[nums.length -1];
22+
23+
for(int i=0; i<nums.length -1; i++) {
24+
if (i==0) {
25+
max[0] = nums[0];
26+
continue;
27+
}
28+
if(i ==1) {
29+
max[1] = Math.max(nums[0], nums[1]);
30+
continue;
31+
}
32+
max[i] = Math.max(max[i-2] +nums[i], max[i-1]);
33+
}
34+
35+
for(int i=1; i<nums.length ; i++) {
36+
if (i==1) {
37+
max2[0] = nums[1];
38+
continue;
39+
}
40+
if(i ==2) {
41+
max2[1] = Math.max(nums[1], nums[2]);
42+
continue;
43+
}
44+
max2[i-1] = Math.max(max2[i-3] +nums[i], max2[i-2]);
45+
}
46+
47+
return Math.max(max[max.length -1], max2[max.length-1]);
48+
49+
50+
51+
52+
53+
}
54+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
3+
class Solution {
4+
5+
private HashMap<Integer, Integer> map = new HashMap<>();
6+
public int coinChange(int[] coins, int amount) {
7+
8+
// 刷硬币的问题
9+
//用多少次硬币能解决问题。
10+
// 解决问题的标志是什么?--》 关键得找出这个状态转移方程来。
11+
12+
// 想不出来,超时了,看答案。
13+
14+
//递归往回找。 StackOverFlow了。。
15+
16+
17+
// 说实话想不通。
18+
// 看代码都有点看不懂。。
19+
20+
// 多看了几遍答案,现在来自己手写。
21+
if(amount == 0) {
22+
return 0;
23+
}
24+
if(map.get(amount) != null){
25+
return map.get(amount);
26+
}
27+
28+
int min = Integer.MAX_VALUE; // 其实只要比amount大就可以了。
29+
for (int coin : coins) {
30+
int current = 0;
31+
if (amount >= coin) {
32+
int next = coinChange(coins, amount - coin);
33+
if(next >=0) {
34+
current = next + 1;
35+
}
36+
}
37+
38+
if(current > 0) {
39+
//说明至少找到了。要去找最小的了。
40+
min = Math.min(min, current);
41+
}
42+
}
43+
44+
int finalCount = (min==Integer.MAX_VALUE) ? -1 : min;
45+
map.put(amount,finalCount);
46+
return finalCount;
47+
}
48+
}

0 commit comments

Comments
 (0)