Skip to content

Commit f31d3c0

Browse files
committed
DP
经典的矩阵路径问题 爬楼梯问题 强盗抢劫 最长递增子序列LIS
1 parent 8c4a439 commit f31d3c0

9 files changed

+257
-0
lines changed

src/DP/信件排错.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
* 信件错排
6+
7+
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信的方式数量。
8+
9+
定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。
10+
假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。
11+
根据 i 和 k 是否相等,有两种情况:
12+
① i==k,交换 i 和 k 的信后,它们的信和信封在正确的位置,但是其余 i-2 封信有 dp[i-2] 种错误装信的方式。
13+
由于 j 有 i-1 种取值,因此共有 (i-1)*dp[i-2] 种错误装信方式。
14+
② i != k,交换 i 和 j 的信后,第 i 个信和信封在正确的位置,其余 i-1 封信有 dp[i-1] 种错误装信方式。
15+
由于 j 有 i-1 种取值,因此共有 (n-1)*dp[i-1] 种错误装信方式。
16+
综上所述,错误装信数量方式数量为:
17+
18+
19+
20+
dp[N] 即为所求。
21+
22+
和上楼梯问题一样,dp[i] 只与 dp[i-1] 和 dp[i-2] 有关,因此也可以只用两个变量来存储 dp[i-1] 和 dp[i-2]。
23+
24+
25+
*/
26+
public class 信件排错 {
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 强盗在环形街区抢劫 {
7+
public static void main(String[] args) {
8+
int []a = {1,2};
9+
int []b = {1,2,3};
10+
int []c = {1,3,2,4};
11+
int []d = {6,4,2,5,9};
12+
System.out.println(rob(a));
13+
System.out.println(rob(b));
14+
System.out.println(rob(c));
15+
System.out.println(rob(d));
16+
}
17+
public static int rob(int[] nums) {
18+
if (nums == null || nums.length == 0) return 0;
19+
if (nums.length == 1)return nums[0];
20+
if (nums.length == 2)return nums[0] > nums[1] ? nums[0] : nums[1];
21+
int []dp = new int[nums.length + 1];
22+
//dp代表最右只抢到第n家时的总钱数。
23+
//如果抢了第一家
24+
dp[1] = nums[0];
25+
dp[2] = nums[0] > nums[1] ? nums[0] : nums[1];
26+
for (int i = 3;i < nums.length;i ++) {
27+
dp[i] = Math.max(dp[i - 2] + nums[i - 1], dp[i - 1]);
28+
}
29+
int max = dp[nums.length - 1];
30+
//如果不抢第一家
31+
dp[1] = 0;
32+
dp[2] = nums[1];
33+
for (int i = 3;i <= nums.length;i ++) {
34+
dp[i] = Math.max(dp[i - 2] + nums[i - 1], dp[i - 1]);
35+
}
36+
37+
if (dp[nums.length] > max)max = dp[nums.length];
38+
return max;
39+
}
40+
}

src/DP/强盗抢劫.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 强盗抢劫 {
7+
public static void main(String[] args) {
8+
int []a = {1,3,5,7,2};
9+
int []b = {2,6,9,1};
10+
System.out.println(rob(a));
11+
System.out.println(rob(b));
12+
}
13+
public static int rob(int[] nums) {
14+
if (nums == null || nums.length == 0) return 0;
15+
if (nums.length == 1)return nums[0];
16+
if (nums.length == 2)return nums[0] > nums[1] ? nums[0] : nums[1];
17+
int []dp = new int[nums.length + 1];
18+
//dp代表最右只抢到第n家时的总钱数。
19+
dp[1] = nums[0];
20+
dp[2] = nums[0] > nums[1] ? nums[0] : nums[1];
21+
for (int i = 3;i <= nums.length;i ++) {
22+
dp[i] = Math.max(dp[i - 2] + nums[i - 1], dp[i - 1]);
23+
}
24+
return dp[nums.length];
25+
}
26+
}

src/DP/最长摆动子序列.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 最长摆动子序列 {
7+
public static void main(String[] args) {
8+
int []a = {1,7,4,9,2,5};
9+
int []b = {1,17,5,10,13,15,10,5,16,8};
10+
int []c = {1,2,3,4,5,6,7,8,9};
11+
int []d = {0,0,0,0,1,0};
12+
System.out.println(wiggleMaxLength(a));
13+
System.out.println(wiggleMaxLength(b));
14+
System.out.println(wiggleMaxLength(c));
15+
System.out.println(wiggleMaxLength(d));
16+
17+
}
18+
public static int wiggleMaxLength(int[] nums) {
19+
if (nums.length == 0)return 0;
20+
int []up = new int[nums.length];
21+
int []down = new int[nums.length];
22+
up[0] = 1;
23+
down[0] = 1;
24+
for (int i = 1;i < nums.length;i ++) {
25+
if (nums[i] > nums[i - 1]) {
26+
up[i] = down[i - 1] + 1;
27+
down[i] = down[i - 1];
28+
}else if (nums[i] < nums[i - 1]) {
29+
down[i] = up[i - 1] + 1;
30+
up[i] = up[i - 1];
31+
}else {
32+
up[i] = up[i - 1];
33+
down[i] = down[i - 1];
34+
}
35+
}
36+
return Math.max(down[nums.length - 1], up[nums.length - 1]);
37+
}
38+
}

src/DP/最长递增子序列.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 最长递增子序列 {
7+
public static void main(String[] args) {
8+
int []a = {10,9,2,5,3,4};
9+
int []b = {10, 9, 2, 5, 3, 7, 101, 18};
10+
int []c = {4,10,4,3,8,9};
11+
System.out.println(lengthOfLIS(a));
12+
System.out.println(lengthOfLIS(b));
13+
System.out.println(lengthOfLIS(c));
14+
}
15+
public static int lengthOfLIS(int[] nums) {
16+
if (nums == null || nums.length == 0)return 0;
17+
if (nums.length == 1)return 1;
18+
int []dp = new int[nums.length];
19+
dp[0] = 1;
20+
//int []c = {4,10,4,3,8,9};
21+
for (int i = 1;i < nums.length;i ++) {
22+
int max = 1;
23+
for (int j = 0;j < i;j ++) {
24+
if (nums[i] > nums[j]) {
25+
max = Math.max(max, dp[j] + 1);
26+
}
27+
dp[i] = max;
28+
}
29+
}
30+
int max = 0;
31+
for (int i = 0;i < nums.length;i ++) {
32+
max = Math.max(dp[i], max);
33+
}
34+
return max;
35+
}
36+
}

src/DP/母牛生产.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
* * 母牛生产
6+
7+
程序员代码面试指南-P181
8+
9+
题目描述:假设农场中成熟的母牛每年都会生 1 头小母牛,并且永远不会死。
10+
第一年有 1 只小母牛,从第二年开始,母牛开始生小母牛。
11+
每只小母牛 3 年之后成熟又可以生小母牛。给定整数 N,求 N 年后牛的数量。
12+
13+
第 i 年成熟的牛的数量为:
14+
15+
16+
*/
17+
18+
public class 母牛生产 {
19+
}

src/DP/爬楼梯方法总数.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 爬楼梯方法总数 {
7+
public int climbStairs(int n) {
8+
if (n == 1 || n == 2)return n;
9+
int []dp = new int[n + 1];
10+
dp[1] = 1;
11+
dp[2] = 2;
12+
for (int i = 3;i <= n;i ++ ) {
13+
dp[i] = dp[i - 1] + dp[i - 2];
14+
}
15+
return dp[n];
16+
}
17+
}

src/DP/矩阵的总路径数.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 矩阵的总路径数 {
7+
public static void main(String[] args) {
8+
9+
}
10+
public int uniquePaths(int m, int n) {
11+
int [][]dp = new int[m][n];
12+
for (int i = 0;i < m;i ++) {
13+
dp[i][0] = 1;
14+
}
15+
for (int j = 0;j < n;j ++) {
16+
dp[0][j] = 1;
17+
}
18+
19+
for (int i = 1;i < m;i ++) {
20+
for (int j = 1;j < n;j ++) {
21+
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
22+
}
23+
}
24+
return dp[m - 1][n - 1];
25+
}
26+
}

src/DP/矩阵的最小路径和.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package DP;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/4.
5+
*/
6+
public class 矩阵的最小路径和 {
7+
public static void main(String[] args) {
8+
9+
}
10+
public int minPathSum(int[][] grid) {
11+
int m = grid.length;
12+
int n = grid[0].length;
13+
int [][]dp = new int[m][n];
14+
dp[0][0] = grid[0][0];
15+
for (int i = 1;i < m;i ++) {
16+
dp[i][0] = dp[i - 1][0] + grid[i][0];
17+
}
18+
for (int j = 1;j < n;j ++) {
19+
dp[0][j] = dp[0][j - 1] + grid[0][j];
20+
}
21+
for (int i = 1;i < m;i ++) {
22+
for (int j = 1;j < n;j ++) {
23+
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
24+
}
25+
}
26+
return dp[m - 1][n - 1];
27+
}
28+
}

0 commit comments

Comments
 (0)