代码随想录|Day25|贪心01

分发饼干

  • 比较简单的贪心算法
class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort()
        s.sort()
        res = 0
        m,n = len(s),len(g)
        i,j = 0,0
        while(i<m and j<n):
            if s[i]>=g[j]:
                i,j,res = i+1,j+1,res+1
            else:
                i+=1
        return res

376. 摆动序列

  • 边界分析有点麻烦,一度放弃,直接看了解析
  • 动规的做法也没想到,挫败
## 贪心
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        N = len(nums)
        preD = 0
        curD = 0
        res = 1
        for i in range(N-1):
            curD = nums[i+1]-nums[i]
            if preD<=0 and curD>0 or preD>=0 and curD<0: 
                res += 1
                preD = curD
        return res
## 动规,最后要加一个1,因为少算了开头的数字
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        up,down = 0,0
        for i in range(len(nums)-1):
            if nums[i+1]-nums[i]>0:
                up = down+1
            elif nums[i+1]-nums[i]<0:
                down = up+1
        return max(down,up)+1

53. 最大子数组和

  • 写的贪心没有oc,看了答案才理清顺序
  • 动态规划比较好理解一些,写出来发现这个贪心就像是简化版动规
## 贪心
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        temp = 0
        ans = -float('inf')
        for i in range(len(nums)):
            temp = temp+nums[i]
            if ans<temp:
                ans = temp
            if temp<0: temp = 0  ## 注意在这里恢复0
        return ans
## 动态规划
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        dp = [0]*len(nums)
        ans = -float('inf')
        temp = 0
        for i in range(len(nums)):
            dp[i] = max(nums[i],nums[i]+dp[i-1])
            ans = max(ans,dp[i])
        return ans

55.跳跃游戏

  • 注意需要跳的下标只需要 len-1
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        left = 0
        right = 0
        while(left<len(nums) and left<=right):
            right = max(right,left + nums[left])
            left += 1
        return False if right<len(nums)-1 else True

45.跳跃游戏 II

  • 比较难想出来简洁的做法,只能多练练,孰能生巧
  • 贪心2的写法更加简洁,关键在遍历时,不遍历最后一个下标;最后一个下标是需要达到的==跳出长度为len-1的数组外
## 贪心1
class Solution:
    def jump(self, nums: List[int]) -> int:
        if len(nums)==1:
            return 0
        curD = 0
        nextD = 0
        res = 0
        for i in range(len(nums)): 
            nextD = max(nextD,nums[i]+i)
            if i==curD:
                res += 1
                curD = nextD
                if curD>=len(nums)-1:
                    break
        return res
## 贪心2
class Solution:
    def jump(self, nums: List[int]) -> int:
        curD = 0
        nextD = 0
        res = 0
        for i in range(len(nums)-1): ###这里是关键
            nextD = max(nextD,nums[i]+i)
            if i==curD:
                res += 1
                curD = nextD
        return res

1005. K 次取反后最大化的数组和

  • 常规写出来的if-else一点都不简洁,还得两次排序
  • 应该按照绝对值排序的,这样写出来会比较简洁
class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort()
        i = 0
        while(i<k and i<len(nums)):
            if nums[i]<0:
                nums[i] = -nums[i]
                i += 1
            elif nums[i]==0 or (k-i)%2==0:
                break
            else:
                if nums[i]>nums[i-1]:
                    nums[i-1] = -nums[i-1]
                else:
                    nums[i] = -nums[i]
                i += 1
                break
            
        if i<k and (k-i)%2!=0:
            nums.sort()
            nums[0] = -nums[0]
            
        return sum(nums)
## 按绝对值排序的写法
class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort(key=lambda x:abs(x),reverse=True)
        for i in range(len(nums)):
            if nums[i]<0:
                nums[i] = -nums[i]
                k-=1
            if k==0:
                return sum(nums)
        if k%2==1:
            nums[-1] = -nums[-1]
        return sum(nums)

你可能感兴趣的:(力扣刷题,python,leetcode,贪心算法)