代码随想录第三十一天

第八章 贪心算法 part01

理论基础

https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
在这里插入图片描述

455.分发饼干

https://programmercarl.com/0455.%E5%88%86%E5%8F%91%E9%A5%BC%E5%B9%B2.html

思路1:优先考虑饼干,小饼干先喂饱小胃口

  1. 首先,使用Arrays.sort(g)和Arrays.sort(s)对两个数组g和s进行排序,将它们从小到大排列,以便后续的分配。
  2. 然后,定义两个变量start和count,start用于记录已经满足胃口的孩子的数量,count用于记录满足胃口的孩子的总数。
  3. 使用一个for循环遍历数组s,表示遍历每一个饼干。
  4. 在循环中,首先判断start是否小于数组g的长度,并且判断当前饼干s[i]的大小是否能够满足孩子的胃口g[start]。
  5. 如果满足条件,表示当前饼干可以满足当前孩子的胃口,将start和count都加1,表示已经满足了一个孩子的需求。
  6. 循环结束后,返回count,即为满足胃口的孩子的总数。

这个算法的思路是优先考虑饼干,将饼干从小到大排序,然后遍历每一个饼干,看是否能够满足孩子的胃口,如果能够满足,则计数器加1,同时更新start指针,表示已经满足了一个孩子的需求。最后返回计数器的值,即为满足胃口的孩子的总数。

Java

class Solution {
    // 思路1:优先考虑饼干,小饼干先喂饱小胃口
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int start = 0;
        int count = 0;
        for (int i = 0; i < s.length && start < g.length; i++) {
            if (s[i] >= g[start]) {
                start++;
                count++;
            }
        }
        return count;
    }
}

完整代码

package leetcode.editor.cn;

import java.util.*;
class ID455AssignCookies{
	public static void main(String[] args) {
		int[] g = {1, 4, 3};
		int[] s = {1, 2};

		Solution solution = new Solution();
		int maxCount = solution.findContentChildren(g, s);
		System.out.println("最大满足孩子数量:" + maxCount);


	}
//leetcode submit region begin(Prohibit modification and deletion)
static class Solution {
    public int findContentChildren(int[] g, int[] s) {
		Arrays.sort(g);
		Arrays.sort(s);
		int start = 0;
		int count = 0;
		for (int i = 0; i < s.length && start < g.length; i++) {
			if (s[i] >= g[start]) {
				start++;
				count++;
			}

		}

		return count;

    }
}
//leetcode submit region end(Prohibit modification and deletion)

}

思路2:优先考虑胃口,先喂饱大胃口

class Solution {
    // 思路2:优先考虑胃口,先喂饱大胃口
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int count = 0;
        int start = s.length - 1;
        // 遍历胃口
        for (int index = g.length - 1; index >= 0; index--) {
            if(start >= 0 && g[index] <= s[start]) {
                start--;
                count++;
            }
        }
        return count;
    }
}

376. 摆动序列

https://programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html

Java

class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }
        //当前差值
        int curDiff = 0;
        //上一个差值
        int preDiff = 0;
        int count = 1;
        for (int i = 1; i < nums.length; i++) {
            //得到当前差值
            curDiff = nums[i] - nums[i - 1];
            //如果当前差值和上一个差值为一正一负
            //等于0的情况表示初始时的preDiff
            if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
                count++;
                preDiff = curDiff;
            }
        }
        return count;
    }
}
// DP
class Solution {
    public int wiggleMaxLength(int[] nums) {
        // 0 i 作为波峰的最大长度
        // 1 i 作为波谷的最大长度
        int dp[][] = new int[nums.length][2];

        dp[0][0] = dp[0][1] = 1;
        for (int i = 1; i < nums.length; i++){
            //i 自己可以成为波峰或者波谷
            dp[i][0] = dp[i][1] = 1;

            for (int j = 0; j < i; j++){
                if (nums[j] > nums[i]){
                    // i 是波谷
                    dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
                }
                if (nums[j] < nums[i]){
                    // i 是波峰
                    dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
                }
            }
        }

        return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
    }
}

53. 最大子序和

https://programmercarl.com/0053.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C.html

Java

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums.length == 1){
            return nums[0];
        }
        int sum = Integer.MIN_VALUE;
        int count = 0;
        for (int i = 0; i < nums.length; i++){
            count += nums[i];
            sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
            if (count <= 0){
                count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
            }
        }
       return sum;
    }
}
// DP 方法
class Solution {
    public int maxSubArray(int[] nums) {
        int ans = Integer.MIN_VALUE;
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        ans = dp[0];

        for (int i = 1; i < nums.length; i++){
            dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
            ans = Math.max(dp[i], ans);
        }

        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值