leecode更新

This commit is contained in:
markilue 2023-02-06 14:31:29 +08:00
parent 5b48986cff
commit 6040c2ab95
6 changed files with 332 additions and 3 deletions

View File

@ -19,7 +19,7 @@ import java.util.Comparator;
*
* @Version: 1.0
*/
public class FindContentChildren {
public class T01_FindContentChildren {
@Test

View File

@ -15,7 +15,7 @@ import org.junit.Test;
* 给你一个整数数组 nums 返回 nums 中作为 摆动序列 最长子序列的长度
* @Version: 1.0
*/
public class WiggleMaxLength {
public class T02_WiggleMaxLength {
@Test

View File

@ -12,7 +12,7 @@ import org.junit.Test;
* 子数组 是数组中的一个连续部分
* @Version: 1.0
*/
public class MaxSubArray {
public class T03_MaxSubArray {
@Test
public void test(){

View File

@ -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;
}
}

View File

@ -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]<num[i-1]+1)
* 3)dp初始化:dp[0][0]=1;dp[0][1]=1;
* 4)dp遍历顺序:从前往后
* 5)dp举例推导: nums = [1,17,5,10,13,15,10,5,16,8]为例
* [0 1]
* 1: 1 1
* 17: 2 1
* 5: 2 3
* 10: 4 3
* 13: 4 3
* 15: 4 3
* 10: 4 4
* 5: 4 5
* 16: 6 5
* 8: 6 7
* @param nums
* @return
*/
public int wiggleMaxLength2(int[] nums) {
int n = nums.length;
if (n < 2) {
return n;
}
int[] up = new int[n];
int[] down = new int[n];
up[0] = down[0] = 1;
for (int i = 1; i < n; i++) {
if (nums[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]);
}
}

View File

@ -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);
}
}