455. Assign Cookies 376. Wiggle Subsequence 53. Maximum Subarray

455. Assign Cookies

Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie.

Each child i has a greed factor g[i], which is the minimum size of a cookie that the child will be content with 满足; and each cookie j has a size s[j]. If s[j] >= g[i], we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

Greed : Big cookies first.

class Solution:
    def findContentChildren(self, g, s):
        g.sort()  # 将孩子的贪心因子排序
        s.sort()  # 将饼干的尺寸排序
        index = len(s) - 1  # 饼干数组的下标,从最后一个饼干开始
        result = 0  # 满足孩子的数量
        for i in range(len(g)-1, -1, -1):  # 遍历胃口,从最后一个孩子开始
            if index >= 0 and s[index] >= g[i]:  # 遍历饼干
                result += 1
                index -= 1
        return result

 Greed : Small cookies first

class Solution:
    def findContentChildren(self, g, s):
        g.sort()  # 将孩子的贪心因子排序
        s.sort()  # 将饼干的尺寸排序
        index = 0
        for i in range(len(s)):  # 遍历饼干
            if index < len(g) and g[index] <= s[i]:  # 如果当前孩子的贪心因子小于等于当前饼干尺寸
                index += 1  # 满足一个孩子,指向下一个孩子
        return index  # 返回满足的孩子数目

 

376. Wiggle Subsequence

wiggle sequence 摆动序列 is a sequence where the differences between successive连续的 numbers strictly(严格地) alternate(交替) between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.

  • For example, [1, 7, 4, 9, 2, 5] is a wiggle sequence because the differences (6, -3, 5, -7, 3) alternate between positive and negative.
  • In contrast 相反[1, 4, 7, 2, 5] and [1, 7, 4, 5, 5] are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.

subsequence is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Given an integer array nums, return the length of the longest wiggle subsequence of nums.

 Idea 1 (greedy solution)

Time complexity: O(n)
Space complexity: O(1)

Local optimization: delete the nodes on the monotonic slope 单调坡 (excluding the nodes at the ends of the monotonic slope), then this slope can have two local peaks.

Overall optimization: the whole sequence has the most local peaks, thus achieving the longest wiggle sequence

There are three types of situations to consider for this question:

  • Case 1: there are flat slopes平坡 in the up and down slopes
  • Case 2: Array of heads and tails
  • Case 3: Flat slopes in monotonic slopes
     

case1:

case2:

 

case3:

 

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

        for i in range(len(nums)-1):
            cur_dif = nums[i+1] - nums[i]
            if cur_dif * pre_dif <= 0 and cur_dif != 0: #must <= 0, cuz initial pre_diff = 0
                count += 1
                pre_dif = cur_dif
        
        return count

Idea 2 (dynamic programming)

Time complexity: O(n^2)
Space complexity: O(n)

way1:

class Solution:
    def wiggleMaxLength(self, nums):
        dp = [[0, 0] for _ in range(len(nums))]  # 创建二维dp数组,用于记录摆动序列的最大长度
        dp[0][0] = dp[0][1] = 1  # 初始条件,序列中的第一个元素默认为峰值,最小长度为1
        for i in range(1, len(nums)):
            dp[i][0] = dp[i][1] = 1  # 初始化当前位置的dp值为1
            for j in range(i):
                if nums[j] > nums[i]:
                    dp[i][1] = max(dp[i][1], dp[j][0] + 1)  # 如果前一个数比当前数大,可以形成一个上升峰值,更新dp[i][1]
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i][0] = max(dp[i][0], dp[j][1] + 1)  # 如果前一个数比当前数小,可以形成一个下降峰值,更新dp[i][0]
        return max(dp[-1][0], dp[-1][1])  # 返回最大的摆动序列长度

simplified:

class Solution:
    def wiggleMaxLength(self, nums):
        if len(nums) <= 1:
            return len(nums)  # 如果数组长度为0或1,则返回数组长度
        
        up = down = 1  # 记录上升和下降摆动序列的最大长度
        for i in range(1, len(nums)):
            if nums[i] > nums[i-1]:
                up = down + 1  # 如果当前数比前一个数大,则可以形成一个上升峰值increasinng peak 
            elif nums[i] < nums[i-1]:
                down = up + 1  # 如果当前数比前一个数小,则可以形成一个下降峰值decreasing peak
        
        return max(up, down)  # 返回上升和下降摆动序列的最大长度

53. Maximum Subarray

Given an integer array nums, find the subarray with the largest sum, and return its sum.

violent solution 1:  Exceeding time limits

class Solution:
    def maxSubArray(self, nums):
        result = float('-inf')  # 初始化结果为负无穷大
        for i in range(len(nums)):  # 设置起始位置
            count = 0
            for j in range(i, len(nums)):  # 从起始位置i开始遍历寻找最大值
                count += nums[j]
                result = max(count, result)  # 更新最大值
        return result

 violent solution 2: pass

class Solution:
    def maxSubArray(self, nums):
        result = float('-inf')  # 初始化结果为负无穷大
        count = 0
        for i in range(len(nums)):
            count += nums[i]
            if count > result:  # 取区间累计的最大值(相当于不断确定最大子序终止位置)
                result = count
            if count <= 0:  # 相当于重置最大子序起始位置,因为总和为负数了,理解为左边的所有加在一起是负数
                count = 0
        return result

dp:Dynamic Programming

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        dp = [float('-inf')] * len(nums)
        dp[0] = nums[0]
        result = dp[0]

        for i in range(1, len(nums)):
            dp[i] = max(dp[i-1] + nums[i], nums[i]) #!!!dp[i] represents the largest sum at this position,including this number
            if dp[i] > result:
                result = dp[i]     
        return result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值