代码随想录第31天|455. 分发饼干、376. 摆动序列、53. 最大子数组和

57 阅读2分钟

455. 分发饼干

1. first idea

每一块饼干优先满足能够满足的胃口最大的孩子。 对孩子按照胃口从大到小降序排列, 对饼干按照大小从小到大升序排列。 一个双层循环,外层饼干遍历,内层胃口遍历。一旦遇到能满足的的胃口立刻把饼干给他。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        lh_s_list = sorted(s)
        hl_g_list = sorted(g, reverse=True)

        count = 0
        for s_idx in range(len(lh_s_list)):
            for g_idx in range(len(hl_g_list)):
                if (lh_s_list[s_idx] >= hl_g_list[g_idx]) and (hl_g_list[g_idx] > 0):
                    lh_s_list[s_idx] = 0
                    hl_g_list[g_idx] = 0
                    count += 1
                    break
        return count

2. difficulties during realization

sorted(my_list, reverse=True)

3. doc

代码随想录 (programmercarl.com) 思路不一样,大胃口应该先挑大饼干,如果大饼干不能满足,再换人,如果能满足就给他。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        hl_s_list = sorted(s, reverse=True)  # 饼干
        hl_g_list = sorted(g, reverse=True)  # 胃口

        s_idx = 0
        for g_idx in range(len(hl_g_list)):
            if (s_idx < len(hl_s_list)) and (hl_s_list[s_idx] >= hl_g_list[g_idx]):
                s_idx += 1
        return s_idx

376. 摆动序列

1. first idea

  1. 如果单调递减,就应该把最小的纳为下一个
  2. 同理,如果单调递增,也应该把最大的纳为下一个

2. doc

代码随想录 (programmercarl.com) 思路很简单,但是要检查单调性很难,不是通过pre_diff和cur_diff两段相邻的走势判断的。

pre_diff不应该紧紧相邻在cur_diff左边,而是应该保留上一个拐点的cur_diff.

宗旨就是一定要跳过平线段。 pre_diff只存上一段不平的线段。(pre_diff=cur_diff只发生在检测到一个拐点的时候) 这样才能避免两段上坡中间由平坡时,将第二段上坡的起点看作拐点的问题。

在这个基础上,我们判断拐点就一条:

  1. 路中间异号,
  2. 路开头:假设前面有半段平坡,且后半段上坡,这算一个拐点,如果后半段也平就不行了,直到碰到上坡。
  3. 路结尾:最后默认存在一个拐点!!!真有意思,无法用人类的思维理解这个事情,当作是经验吧。
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        
        if len(nums) <= 1:
            return len(nums)
        pre_diff = cur_diff = 0.0
        max_len = 1
        for idx in range(1, len(nums)):
            cur_diff = nums[idx] - nums[idx - 1]
            if (cur_diff * pre_diff <= 0) and (cur_diff != 0):
                max_len += 1
                pre_diff = cur_diff
        return max_len
                    
                

53. 最大子数组和

1. doc

代码随想录 (programmercarl.com)

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。

全局最优:选取最大“连续和”

局部最优的情况下,并记录最大的“连续和”,可以推出全局最优

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        start_idx = 0
        sum_val = 0
        max_sum = 0
        for end_idx in range(start_idx, len(nums)):
            sum_val += nums[end_idx]
            if sum_val < 0:
                start_idx = end_idx + 1
                sum_val = 0
                continue
            max_sum = max(sum_val, max_sum)
        if max_sum == 0:
            return max(nums) # 如果全是负数,只能将最大的负数作为最大和了。
        return max_sum