diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/MaxProfit.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T04_MaxProfit.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/greedy/MaxProfit.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T04_MaxProfit.java index da602e8..1df1767 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/MaxProfit.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T04_MaxProfit.java @@ -13,7 +13,7 @@ import org.junit.Test; * 返回 你能获得的 最大 利润。 * @Version: 1.0 */ -public class MaxProfit { +public class T04_MaxProfit { @Test public void test(){ int[] prices = {7, 1, 5, 3, 6, 4}; diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/CanJump.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T05_CanJump.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/greedy/CanJump.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T05_CanJump.java index 9c0f6cf..bdf09f0 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/CanJump.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T05_CanJump.java @@ -14,7 +14,7 @@ import org.junit.Test; * 判断你是否能够到达最后一个下标 * @Version: 1.0 */ -public class CanJump { +public class T05_CanJump { @Test public void test(){ diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/Jump.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T06_Jump.java similarity index 97% rename from Leecode/src/main/java/com/markilue/leecode/greedy/Jump.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T06_Jump.java index 6851d5e..fdac4c9 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/Jump.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T06_Jump.java @@ -2,9 +2,6 @@ package com.markilue.leecode.greedy; import org.junit.Test; -import java.util.ArrayList; -import java.util.HashSet; - /** * @BelongsProject: Leecode * @BelongsPackage: com.markilue.leecode.greedy @@ -16,7 +13,7 @@ import java.util.HashSet; * 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 * @Version: 1.0 */ -public class Jump { +public class T06_Jump { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java index ee3b0a3..5174daa 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java @@ -32,7 +32,7 @@ public class T02_WiggleMaxLength { @Test public void test2() { - int[] nums = {3,3,3,2,5}; + int[] nums = {3, 3, 3, 2, 5}; System.out.println(wiggleMaxLength(nums)); } @@ -46,17 +46,17 @@ public class T02_WiggleMaxLength { int result = 1; int lastNum = nums[0]; - Boolean flag=null; + Boolean flag = null; for (int i = 1; i < nums.length; i++) { - if(flag==null){ - if(nums[i]!=lastNum){ + if (flag == null) { + if (nums[i] != lastNum) { result++; flag = nums[i] > lastNum ? true : false; } } - if (flag!=null&&((flag && nums[i] < lastNum) || (!flag && nums[i] > lastNum))) { + if (flag != null && ((flag && nums[i] < lastNum) || (!flag && nums[i] > lastNum))) { result++; flag = !flag; } @@ -78,7 +78,7 @@ public class T02_WiggleMaxLength { int curdiff = 0; //记录现在的差值 int prediff = 0; //记录上次的差值 - for (int i = 0; i < nums.length-1; i++) { + for (int i = 0; i < nums.length - 1; i++) { curdiff = nums[i + 1] - nums[i]; if ((prediff >= 0 && curdiff < 0) || (prediff <= 0 && curdiff > 0)) { result++; diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T04_MaxProfit.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T04_MaxProfit.java new file mode 100644 index 0000000..c93b6f6 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T04_MaxProfit.java @@ -0,0 +1,113 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: markilue + *@CreateTime: 2023-02-08 11:10 + *@Description: + * TODO 力扣122题 买卖股票的最佳时机II: + * 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 + * 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 + * 返回 你能获得的 最大 利润 。 + *@Version: 1.0 + */ +public class T04_MaxProfit { + + @Test + public void test() { + int[] prices = {7, 1, 5, 3, 6, 4}; + System.out.println(maxProfit1(prices)); + } + + + /** + * 贪心思路:可以把当前的利润分为:昨天有股票今天卖了(prices[i]>lastPrice);和昨天有股票今天买了(prices[i] lastPrice) { + profit += prices[i] - lastPrice; + } + //无论卖不卖都需要重置当前 + lastPrice = prices[i]; + + } + return profit; + + } + + + /** + * dp思路:可以把今天今天的收益分为 今天手里有股票 和 今天手里没股票 两者的最大值 + * TODO dp五部曲: + * 1)dp定义:dp[i][0]表示第i天手里没股票的收益,dp[i][1]表示第i天手里有股票的收益 + * 2)dp状态转移方程: + * 1.dp[i][0] 手里没有股票的收益:昨天没有今天也没有 和 昨天有今天卖了 + * dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]) + * 2.dp[i][1] 手里有股票的收益: 昨天有今天没买 和 昨天有今天买了 + * dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]) + * 3)dp初始化:dp[0][0]=0;dp[0][1]=-prices[0] + * 4)dp遍历顺序:从前往后 + * 5)dp举例推导: prices = [7,1,5,3,6,4]为例: + * [0 1] + * 7: 0 -7 + * 1: 0 -1 + * 5: 4 -1 + * 3: 4 1 + * 6: 7 1 + * 4: 7 3 + * + */ + public int maxProfit1(int[] prices) { + + int[][] dp=new int[prices.length][2]; + dp[0][0]=0;dp[0][1]=-prices[0]; + for (int i = 1; i < prices.length; i++) { + dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]); + dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]); + } + + return dp[prices.length-1][0]; + + } + + + /** + * 一维dp + * @param prices + * @return + */ + public int maxProfit2(int[] prices) { + + int dp0=0; + int dp1=-prices[0]; + for (int i = 1; i < prices.length; i++) { + dp0=Math.max(dp0,dp1+prices[i]); + dp1=Math.max(dp1,dp0-prices[i]); + } + + return dp0; + + } + + /** + * 官方最快:贪心算法,可能快在不用赋值lastNum 0ma + * @param prices + * @return + */ + public int maxProfit3(int[] prices) { + int ans = 0; + for(int i=1; i< prices.length; i++){ + if(prices[i] > prices[i-1]){ + ans += (prices[i] - prices[i-1]); + } + } + return ans; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T05_CanJump.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T05_CanJump.java new file mode 100644 index 0000000..ab529b5 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T05_CanJump.java @@ -0,0 +1,44 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: markilue + *@CreateTime: 2023-02-08 11:43 + *@Description: + * TODO 力扣55题 跳跃游戏: + * 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 + * 数组中的每个元素代表你在该位置可以跳跃的最大长度。 + * 判断你是否能够到达最后一个下标。 + *@Version: 1.0 + */ +public class T05_CanJump { + + @Test + public void test(){ + int[] nums={2,0}; + System.out.println(canJump(nums)); + } + + /** + * 思路:事实上就是计算,在能到达的范围内的最大值 + * @param nums + * @return + */ + public boolean canJump(int[] nums) { + if (nums.length == 1) return true; + + int maxIndex = 0; + + for (int i = 0; i < nums.length - 1; i++) { + if (i > maxIndex) return false;//遍历到了没法到的地方了还没有找到则到不了了 + maxIndex = Math.max(maxIndex, i + nums[i]); + if (maxIndex >= nums.length - 1) return true;//可以遍历到了,直接返回 + } + + return false;//遍历完了也没有返回ture,则返回false + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T06_Jump.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T06_Jump.java new file mode 100644 index 0000000..97882bd --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T06_Jump.java @@ -0,0 +1,55 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +import java.util.jar.JarEntry; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: markilue + *@CreateTime: 2023-02-08 12:00 + *@Description: + * TODO 力扣45题 跳跃游戏II: + * 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 + * 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处: + * 0 <= j <= nums[i] + * i + j < n + * 返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。 + *@Version: 1.0 + */ +public class T06_Jump { + + @Test + public void test(){ +// int[] nums = {2, 3, 1, 1, 4}; +// int[] nums = {2, 0,1,2}; + int[] nums = {1, 1,1,1}; + System.out.println(jump(nums)); + } + + + /** + * 思路:题设说一定能到;首先用curCover记录当前能覆盖到的位置,maxIndex记录最大的;如果i大过curCover的话就需要加一步 + * @param nums + * @return + */ + public int jump(int[] nums) { + if(nums.length==1)return 0; + + int maxIndex=0;//最大能覆盖的位置 + int curCover=0;//当前没变时,能覆盖的位置 + int step=0; + for (int i = 0; i < nums.length; i++) { + if(i>curCover) { + step++; + curCover=maxIndex; + } + maxIndex=Math.max(maxIndex,i+nums[i]); + if(maxIndex>=nums.length-1)return step+1;//从这里直接跨到最后 + } + + return step+1; + + } +}