day27 代码随想录 | 贪心算法 分发饼干 摆动序列 最大子数组和

455 分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

这个题很自然而然的就是想 让大的去匹配大的,小的去匹配小的。我们将两个数组都排序

用胃口去比较饼干,可以从小到大去匹配,匹配到数组中止,就结束,记录就可以了

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort()
        s.sort()
        i = 0
        j = 0
        while i < len(g) and j < len(s):
            if g[i] <= s[j]:
                i += 1
            j += 1
        
        return i

376 摆动序列

这个是真的难受

我们都知道摆动的条件,那就是三个数,如果两者的差异号,那说明就是正负交替

但是有一些细节

1. 如果有重复元素呢,比如1,2,2,2,1。你的指针改怎么移动和判断呢,我们会得到1和2的差值是1 最后一个2和1的差值是-1,但是你指针应该怎么动,当我们遍历到i=1的时候, nums[i] - nums[i-1] = 1 那么后面 i+1-nums[i] = 0 你需要移动i,直到 最后i为最后,你需要保存你之前的那个1的差值,即pre_gap, 然后拿到你的cur_gap进行比较,但是在这之间,cur_gap是等于0的,你不能直接跳过重开,仍需要记录

2. 初始化的问题。我们直到要保存 pre_gap , cur_gap ,初始应该为多少,总长度result应该为多少

pre_gap == cur_gap为0,result=1的,为什么? 假设是2,2,5,最终的result为2。具体可以看代码随想录。我觉得很简单的想法就是,初始化为1,就是序列最小就是为1

3. 如何判断的问题?如何记录一个result, 当 cur_gap != 0 且pre_gap * cur*gap <=0的时候

result 要+1。 一个很特殊的情况是,如果你判断条件是<,那么对于3,3,5这种一开始pre_gap等于0 的,你用户不会有小于,你就GG了。因此,判断条件需要加上等于,但是还需要满足cur_gap不等于,为什么?就是为了排序排序这种3,3的在我们的序列中!

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return 1

        if len(nums) >= 2:
            pre_gap = nums[1] - nums[0]
            result =  2 if nums[1] != nums[0] else 1  # 这里我没有直接初始化,我是通过加判断
       
        for i in range(2, len(nums)):
            cur_gap = nums[i] - nums[i-1]
            if cur_gap * pre_gap <= 0 and cur_gap != 0 :
                result += 1
                pre_gap = cur_gap
        return result

53 最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

这个题是在百度的面试题里面出现过。理解的核心点,对负数的处理。我们什么时候应该加负数,什么时候应该丢弃负数,重新开始子数列求和。这个题可以用贪心的思想去做,代码很简单,但是真的不好想。还有这个题目是连续的子数列! 你可以能想到我就用暴力解法,这没问题,大不了我双层循环,直接遍历求解,求最大。  对负数的处理我们肯定不是遇到负数就直接重新走一个新的子序列。那么我们应该怎么处理,我们处理的是累加和。也就是第i个元素和前i-1元素的累加和进行比较。如果num[i] + nums[i-1](这里的nums[i-1]已经是累加和了) > nums[i], 这说明,至少前面nums[i-1]是个整数,还可以加在一起;然后比较新的累加和与保存的最大累加和的大小,如果比保存的最大的累加和大,那就赋值新的最大累加和。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return nums[0]

        result = nums[0]
        
        for i in range(1, len(nums):
            if nums[i] + nums[i-1] > nums[i]:
                nums[i] = nums[i] + nums[i-1]
            if nums[i] > result:
                result = nums[i]

        return result

### 代码随想录算法训练营 Day20 学习内容与作业 #### 动态规划专题深入探讨 动态规划是一种通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法[^1]。 #### 主要学习内容 - **背包问题系列** - 背包问题是典型的动态规划应用场景之一。这类题目通常涉及给定容量的背包以及一系列具有不同价值重量的物品,目标是在不超过总容量的情况下最大化所选物品的价值。 - **状态转移方程构建技巧** - 构建合适的状态转移方程对于解决动态规划问题是至关重要的。这涉及到定义好dp数组(或表格),并找到从前一个状态到下一个状态之间的关系表达式[^2]。 - **优化空间复杂度方法** - 对于某些特定类型的DP问题,可以采用滚动数组等方式来减少所需的空间开销,从而提高程序效率[^3]。 #### 实战练习题解析 ##### 题目:零钱兑换 (Coin Change) 描述:给定不同面额的硬币 coins 一个总金额 amount。编写函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 `-1`。 解决方案: ```python def coinChange(coins, amount): dp = [float('inf')] * (amount + 1) dp[0] = 0 for i in range(1, amount + 1): for coin in coins: if i >= coin and dp[i - coin] != float('inf'): dp[i] = min(dp[i], dp[i - coin] + 1) return dp[-1] if dp[-1] != float('inf') else -1 ``` 此段代码实现了基于自底向上的迭代方式解决问题,其中 `dp[i]` 表示达到金额 `i` 所需最小数量的硬币数目[^4]。 ##### 题目:完全平方数 (Perfect Squares) 描述:给出正整数 n ,找出若干个不同的 完全平方数 (比如 1, 4, 9 ...)使得它们的等于n 。问至少需要几个这样的完全平方数? 解答思路同上一题类似,只是这里的“硬币”变成了各个可能的完全平方数值。 ```python import math def numSquares(n): square_nums = set([i*i for i in range(int(math.sqrt(n))+1)]) dp = [float('inf')] *(n+1) dp[0] = 0 for i in range(1,n+1): for sq in square_nums: if i>=sq: dp[i]=min(dp[i],dp[i-sq]+1); return dp[n]; ``` 这段代码同样运用了动态规划的思想去寻找最优解路径,并利用集合存储所有小于等于输入值的最大平方根内的平方数作为候选集[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值