-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
nibnait
committed
Oct 31, 2020
1 parent
9d4a2a9
commit 5e62ed3
Showing
10 changed files
with
714 additions
and
20 deletions.
There are no files selected for viewing
17 changes: 0 additions & 17 deletions
17
...algorithm_practice/Coding_Interview_Guide_2ndEdition/Chapter_04_递归和动态规划/P04_换钱的最少货币数.java
This file was deleted.
Oops, something went wrong.
84 changes: 84 additions & 0 deletions
84
src/main/java/algorithm_practice/LeetCode/code000/M062_不同路径.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package algorithm_practice.LeetCode.code000; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/* | ||
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 | ||
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 | ||
问总共有多少条不同的路径? | ||
例如,上图是一个7 x 3 的网格。有多少可能的路径? | ||
示例 1: | ||
输入: m = 3, n = 2 | ||
输出: 3 | ||
解释: | ||
从左上角开始,总共有 3 条路径可以到达右下角。 | ||
1. 向右 -> 向右 -> 向下 | ||
2. 向右 -> 向下 -> 向右 | ||
3. 向下 -> 向右 -> 向右 | ||
示例 2: | ||
输入: m = 7, n = 3 | ||
输出: 28 | ||
提示: | ||
1 <= m, n <= 100 | ||
题目数据保证答案小于等于 2 * 10 ^ 9 | ||
来源:力扣(LeetCode) | ||
链接:https://leetcode-cn.com/problems/unique-paths | ||
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 | ||
*/ | ||
public class M062_不同路径 { | ||
@Test | ||
public void testCase() { | ||
int m = 3; | ||
int n = 2; | ||
int excepted = 3; | ||
Assert.assertEquals(excepted, uniquePaths(m, n)); | ||
|
||
m = 7; | ||
n = 3; | ||
excepted = 28; | ||
Assert.assertEquals(excepted, uniquePaths(m, n)); | ||
|
||
m = 3; | ||
n = 7; | ||
excepted = 28; | ||
Assert.assertEquals(excepted, uniquePaths(m, n)); | ||
|
||
} | ||
|
||
public int uniquePaths(int m, int n) { | ||
|
||
int[][] dp = new int[m][n]; | ||
|
||
for (int i = 0; i < m; i++) { | ||
dp[i][0] = 1; | ||
} | ||
|
||
for (int i = 0; i < n; i++) { | ||
dp[0][i] = 1; | ||
} | ||
|
||
for (int i = 1; i < m; i++) { | ||
for (int j = 1; j < n; j++) { | ||
dp[i][j] = dp[i-1][j] + dp[i][j-1]; | ||
} | ||
} | ||
|
||
return dp[m-1][n-1]; | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
src/main/java/algorithm_practice/LeetCode/code000/M063_不同路径2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package algorithm_practice.LeetCode.code000; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/* | ||
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 | ||
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 | ||
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? | ||
网格中的障碍物和空位置分别用 1 和 0 来表示。 | ||
说明:m 和 n 的值均不超过 100。 | ||
示例 1: | ||
输入: | ||
[ | ||
[0,0,0], | ||
[0,1,0], | ||
[0,0,0] | ||
] | ||
输出: 2 | ||
解释: | ||
3x3 网格的正中间有一个障碍物。 | ||
从左上角到右下角一共有 2 条不同的路径: | ||
1. 向右 -> 向右 -> 向下 -> 向下 | ||
2. 向下 -> 向下 -> 向右 -> 向右 | ||
来源:力扣(LeetCode) | ||
链接:https://leetcode-cn.com/problems/unique-paths-ii | ||
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 | ||
*/ | ||
public class M063_不同路径2 { | ||
@Test | ||
public void testCase() { | ||
int[][] obstacleGrid = new int[][]{ | ||
{0,0,0}, | ||
{0,1,0}, | ||
{0,0,0}}; | ||
int expected = 2; | ||
Assert.assertEquals(expected, uniquePathsWithObstacles(obstacleGrid)); | ||
|
||
obstacleGrid = new int[][]{ | ||
{1,0}}; | ||
expected = 0; | ||
Assert.assertEquals(expected, uniquePathsWithObstacles(obstacleGrid)); | ||
|
||
obstacleGrid = new int[][]{ | ||
{0,0}, | ||
{0,1}}; | ||
expected = 0; | ||
Assert.assertEquals(expected, uniquePathsWithObstacles(obstacleGrid)); | ||
|
||
obstacleGrid = new int[][]{ | ||
{0,0,0,0,0}, | ||
{0,0,0,0,1}, | ||
{0,0,0,1,0}, | ||
{0,0,1,0,0}}; | ||
expected = 0; | ||
Assert.assertEquals(expected, uniquePathsWithObstacles(obstacleGrid)); | ||
|
||
} | ||
|
||
public int uniquePathsWithObstacles(int[][] obstacleGrid) { | ||
int m = obstacleGrid.length; | ||
if (m == 0) { | ||
return 0; | ||
} | ||
|
||
int n = obstacleGrid[0].length; | ||
if (obstacleGrid[m-1][n-1] == 1) { | ||
return 0; | ||
} | ||
|
||
int[][] dp = new int[m][n]; | ||
|
||
boolean blockFlag = false; | ||
for (int i = 0; i < m; i++) { | ||
if (obstacleGrid[i][0] == 1 || blockFlag) { | ||
dp[i][0] = 0; | ||
blockFlag = true; | ||
} else { | ||
dp[i][0] = 1; | ||
} | ||
} | ||
|
||
blockFlag = false; | ||
for (int i = 0; i < n; i++) { | ||
if (obstacleGrid[0][i] == 1 || blockFlag) { | ||
dp[0][i] = 0; | ||
blockFlag = true; | ||
} else { | ||
dp[0][i] = 1; | ||
} | ||
} | ||
|
||
for (int i = 1; i < m; i++) { | ||
for (int j = 1; j < n; j++) { | ||
if (obstacleGrid[i][j] == 1){ | ||
dp[i][j] = 0; | ||
} else { | ||
dp[i][j] = dp[i-1][j] + dp[i][j-1]; | ||
} | ||
} | ||
} | ||
|
||
return dp[m-1][n-1]; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
src/main/java/algorithm_practice/LeetCode/code100/E198_打家劫舍.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package algorithm_practice.LeetCode.code100; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/* | ||
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 | ||
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 | ||
示例 1: | ||
输入:[1,2,3,1] | ||
输出:4 | ||
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 | ||
偷窃到的最高金额 = 1 + 3 = 4 。 | ||
示例 2: | ||
输入:[2,7,9,3,1] | ||
输出:12 | ||
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 | ||
偷窃到的最高金额 = 2 + 9 + 1 = 12 。 | ||
提示: | ||
0 <= nums.length <= 100 | ||
0 <= nums[i] <= 400 | ||
来源:力扣(LeetCode) | ||
链接:https://leetcode-cn.com/problems/house-robber | ||
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 | ||
*/ | ||
public class E198_打家劫舍 { | ||
@Test | ||
public void testCase() { | ||
int[] nums = new int[]{1,2,3,1}; | ||
int excepted = 4; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{2,7,9,3,1}; | ||
excepted = 12; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
} | ||
|
||
public int rob(int[] nums) { | ||
if (nums.length == 0) { | ||
return 0; | ||
} | ||
|
||
if (nums.length == 1) { | ||
return nums[0]; | ||
} | ||
|
||
// dp[i]: nums[0...i] 偷窃到的最高金额 | ||
int[] dp = new int[nums.length]; | ||
dp[0] = nums[0]; | ||
dp[1] = Math.max(nums[0], nums[1]); | ||
|
||
for (int i = 2; i < nums.length; i++) { | ||
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]); | ||
} | ||
|
||
return dp[nums.length-1]; | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
src/main/java/algorithm_practice/LeetCode/code200/M213_打家劫舍2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package algorithm_practice.LeetCode.code200; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/* | ||
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。 | ||
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,能够偷窃到的最高金额。 | ||
示例 1: | ||
输入:nums = [2,3,2] | ||
输出:3 | ||
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。 | ||
示例 2: | ||
输入:nums = [1,2,3,1] | ||
输出:4 | ||
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。 | ||
偷窃到的最高金额 = 1 + 3 = 4 。 | ||
示例 3: | ||
输入:nums = [0] | ||
输出:0 | ||
提示: | ||
1 <= nums.length <= 100 | ||
0 <= nums[i] <= 1000 | ||
来源:力扣(LeetCode) | ||
链接:https://leetcode-cn.com/problems/house-robber-ii | ||
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 | ||
*/ | ||
public class M213_打家劫舍2 { | ||
@Test | ||
public void testCase() { | ||
int[] nums = new int[]{1, 2, 3, 1}; | ||
int excepted = 4; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{2, 3, 2}; | ||
excepted = 3; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{0}; | ||
excepted = 0; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{1, 1}; | ||
excepted = 1; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{200, 3, 140, 20, 10}; | ||
excepted = 340; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
nums = new int[]{1, 3, 1, 3, 100}; | ||
excepted = 103; | ||
Assert.assertEquals(excepted, rob(nums)); | ||
|
||
} | ||
|
||
public int rob(int[] nums) { | ||
int length = nums.length; | ||
if (length == 1) { | ||
return nums[0]; | ||
} | ||
if (length == 2) { | ||
return Math.max(nums[0],nums[1]); | ||
} | ||
|
||
return Math.max(rob(nums, 0, length - 2), | ||
rob(nums, 1, length - 1)); | ||
} | ||
|
||
private int rob(int[] nums, int begin, int end) { | ||
int[] dp = new int[nums.length]; | ||
dp[begin] = nums[begin]; | ||
dp[begin+1] = Math.max(nums[begin], nums[begin+1]); | ||
|
||
for (int i = begin+2; i <= end; i++) { | ||
dp[i] = Math.max(nums[i] + dp[i - 2], dp[i - 1]); | ||
} | ||
|
||
return dp[end]; | ||
} | ||
|
||
} |
Oops, something went wrong.