From 6040c2ab95ba42d74ee1dc11136fc2a9a3520287 Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Mon, 6 Feb 2023 14:31:29 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...dren.java => T01_FindContentChildren.java} | 2 +- ...axLength.java => T02_WiggleMaxLength.java} | 2 +- ...{MaxSubArray.java => T03_MaxSubArray.java} | 2 +- .../second/T01_FindContentChildren.java | 80 ++++++++++ .../greedy/second/T02_WiggleMaxLength.java | 144 ++++++++++++++++++ .../greedy/second/T03_MaxSubArray.java | 105 +++++++++++++ 6 files changed, 332 insertions(+), 3 deletions(-) rename Leecode/src/main/java/com/markilue/leecode/greedy/{FindContentChildren.java => T01_FindContentChildren.java} (97%) rename Leecode/src/main/java/com/markilue/leecode/greedy/{WiggleMaxLength.java => T02_WiggleMaxLength.java} (99%) rename Leecode/src/main/java/com/markilue/leecode/greedy/{MaxSubArray.java => T03_MaxSubArray.java} (99%) create mode 100644 Leecode/src/main/java/com/markilue/leecode/greedy/second/T01_FindContentChildren.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/greedy/second/T03_MaxSubArray.java diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/FindContentChildren.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T01_FindContentChildren.java similarity index 97% rename from Leecode/src/main/java/com/markilue/leecode/greedy/FindContentChildren.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T01_FindContentChildren.java index 7ce8c92..59ae4d6 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/FindContentChildren.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T01_FindContentChildren.java @@ -19,7 +19,7 @@ import java.util.Comparator; * * @Version: 1.0 */ -public class FindContentChildren { +public class T01_FindContentChildren { @Test diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/WiggleMaxLength.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T02_WiggleMaxLength.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/greedy/WiggleMaxLength.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T02_WiggleMaxLength.java index ea143cf..61c7191 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/WiggleMaxLength.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T02_WiggleMaxLength.java @@ -15,7 +15,7 @@ import org.junit.Test; * 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 * @Version: 1.0 */ -public class WiggleMaxLength { +public class T02_WiggleMaxLength { @Test diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/MaxSubArray.java b/Leecode/src/main/java/com/markilue/leecode/greedy/T03_MaxSubArray.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/greedy/MaxSubArray.java rename to Leecode/src/main/java/com/markilue/leecode/greedy/T03_MaxSubArray.java index 09c94f4..aa856ee 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/MaxSubArray.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/T03_MaxSubArray.java @@ -12,7 +12,7 @@ import org.junit.Test; * 子数组 是数组中的一个连续部分。 * @Version: 1.0 */ -public class MaxSubArray { +public class T03_MaxSubArray { @Test public void test(){ diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T01_FindContentChildren.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T01_FindContentChildren.java new file mode 100644 index 0000000..392b887 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T01_FindContentChildren.java @@ -0,0 +1,80 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +import java.util.Arrays; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: dingjiawen + *@CreateTime: 2023-02-06 10:21 + *@Description: + * TODO 力扣455 分发饼干: + * 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 + * 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。 + * 如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。 + * 你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 + *@Version: 1.0 + */ +public class T01_FindContentChildren { + + @Test + public void test(){ + int[] g = {1, 2, 3}, s = {1, 1}; + System.out.println(findContentChildren(g,s)); + } + + /** + * 让s中最大的依次满足g中最大的,满足不了就满足第二大的 + * 由于需要排序,所以时间复杂度O(nlogn) + * @param g + * @param s + * @return + */ + public int findContentChildren(int[] g, int[] s) { + if (g == null || g.length == 0 || s == null || s.length == 0) { + return 0; + } + + //排序选择最大的 + Arrays.sort(g); + Arrays.sort(s); + int result=0; + int sIndex=s.length-1; + for (int i = g.length-1; i >= 0; i--) { + if(sIndex<0){ + break; + } + if(s[sIndex]>=g[i]){ + //满足了再偏移s + result++; + sIndex--; + } + } + return result; + } + + + /** + * 官方最快 7ms + * 速度击败100%,内存击败47.38% + * @param g + * @param s + * @return + */ + public int findContentChildren1(int[] g, int[] s) { + if(s.length == 0 || g.length == 0) return 0; + Arrays.sort(g); + Arrays.sort(s); + int startIndex = s.length; + int childrenNum = 0; + for(int i = g.length; i > 0 && startIndex > 0; i--) { + if(g[i - 1] <= s[startIndex - 1]) { + childrenNum++; + startIndex--; + } + } + return childrenNum; + } +} 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 new file mode 100644 index 0000000..ee3b0a3 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java @@ -0,0 +1,144 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: dingjiawen + *@CreateTime: 2023-02-06 11:01 + *@Description: + * TODO 力扣376 摆动序列: + * 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 + * 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 + * 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 + * 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 + * 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。 + *@Version: 1.0 + */ +public class T02_WiggleMaxLength { + + @Test + public void test() { + int[] nums = {1, 7, 4, 9, 2, 5}; + System.out.println(wiggleMaxLength(nums)); + } + + @Test + public void test1() { + int[] nums = {1, 17, 5, 10, 13, 15, 10, 5, 16, 8}; + System.out.println(wiggleMaxLength(nums)); + } + + @Test + public void test2() { + int[] nums = {3,3,3,2,5}; + System.out.println(wiggleMaxLength(nums)); + } + + + /** + * 思路:记录遍历到当前位置,如果是单调的就直接继续找下一个,只用记录极值 + * @param nums + * @return + */ + public int wiggleMaxLength(int[] nums) { + + int result = 1; + int lastNum = nums[0]; + Boolean flag=null; + + for (int i = 1; i < nums.length; i++) { + 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))) { + result++; + flag = !flag; + } + lastNum = nums[i]; + } + + return result; + + + } + + /** + * 优秀写法 + * @param nums + * @return + */ + public int wiggleMaxLength1(int[] nums) { + int result = 1; + + int curdiff = 0; //记录现在的差值 + int prediff = 0; //记录上次的差值 + 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++; + prediff = curdiff; + } + + } + + return result; + } + + + /** + * 尝试动态规划法 + * TODO 动态规划五部曲: + * 1)dp定义:dp[i][0]表示第i个数作为山峰的情况;dp[i][1]表示第i个数作为山谷的情况 + * 2)dp状态转移方程: + * 1)dp[i][0]: + * max(dp[i-1][0],dp[i-1][1]&&num[i]>num[i-1]+1) + * 2)dp[i][1]: + * * max(dp[i-1][1],dp[i-1][0]&&num[i] nums[i - 1]) { + up[i] = Math.max(up[i - 1], down[i - 1] + 1); + down[i] = down[i - 1]; + } else if (nums[i] < nums[i - 1]) { + up[i] = up[i - 1]; + down[i] = Math.max(up[i - 1] + 1, down[i - 1]); + } else { + up[i] = up[i - 1]; + down[i] = down[i - 1]; + } + } + return Math.max(up[n - 1], down[n - 1]); + + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T03_MaxSubArray.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T03_MaxSubArray.java new file mode 100644 index 0000000..b17dcf6 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T03_MaxSubArray.java @@ -0,0 +1,105 @@ +package com.markilue.leecode.greedy.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.greedy.second + *@Author: dingjiawen + *@CreateTime: 2023-02-06 12:52 + *@Description: + * TODO 力扣53题 最大子数组和: + * 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 + * 子数组 是数组中的一个连续部分。 + *@Version: 1.0 + */ +public class T03_MaxSubArray { + + @Test + public void test(){ + int[] nums= {5, 4, -1, 7, 8}; + System.out.println(maxSubArray1(nums)); + } + + + /** + * 贪心 + * @param nums + * @return + */ + public int maxSubArray(int[] nums) { + + int maxSum = Integer.MIN_VALUE; + int curSum = 0; + for (int i = 0; i < nums.length; i++) { + curSum += nums[i]; + if (curSum > maxSum) { + maxSum = curSum; + } + + if (curSum < 0) { + curSum = 0; + continue; + } + } + return maxSum; + + } + + + /** + * 动态规划法: + * TODO DP五部曲: + * 1)dp定义:dp[i][0]表示使用num[0-i]时不要当前值的最大值;dp[i][1]表示使用num[0-i]时要之前的最大值 + * 2)dp状态转移方程: + * 1.dp[i][0]不要现在的:要之前不要现在 和 不要之前不要现在 + * dp[i][0]=Max(dp[i-1][0],dp[i-1][1]) + * 2.dp[i][1]要之前的: 要之前要现在 和 不要之前要现在 + * dp[i][1]=Max(dp[i-1][1]+num[i],num[i]) + * 3)dp初始化:dp[i][0]=num[0] + * 4)dp遍历顺序:从前往后 + * 5)dp举例推导:nums = [-2,1,-3,4,-1,2,1,-5,4] + * [0 1] + * i=-2: -2 -2 + * i=1: -2 1 + * i=-3: 1 -2 + * i=4: 1 4 + * i=-1: 4 3 + * i=2: 4 5 + * i=1: 5 6 + * i=-5: 6 1 + * i=4: 6 5 + * @param nums + * @return + */ + public int maxSubArray1(int[] nums) { + + int[][] dp=new int[nums.length][2]; + dp[0][0]=dp[0][1]=nums[0]; + for (int i = 1; i < nums.length; i++) { + dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]); + dp[i][1]=Math.max(dp[i-1][1]+nums[i],nums[i]); + } + + return Math.max(dp[dp.length-1][0],dp[dp.length-1][1]); + + } + + /** + * dp优化 + * @param nums + * @return + */ + public int maxSubArray2(int[] nums) { + + + int last0=nums[0],last1=nums[0]; + for (int i = 1; i < nums.length; i++) { + last0=Math.max(last0,last1); + last1=Math.max(last1+nums[i],nums[i]); + } + + return Math.max(last0,last1); + + } +}