首页 > 编程语言 >Day27 贪心算法part1

Day27 贪心算法part1

时间:2024-08-12 13:27:20浏览次数:13  
标签:nums int Day27 part1 nextDiff 数组 序列 dp 贪心

任务

455. 分发饼干

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

思路

对s和g排序,每次所能满足的最大胃口的孩子,计数。注意要从胃口开始倒序遍历,索引自然递减,而对于尺寸的递减,则通过index的形式,每用掉一个,递减,并且统计分配数量。
注意自然递减不能用尺寸,模拟一下可以发现

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        s.sort()
        g.sort()
        index = len(s)-1
        count = 0
        for i in range(len(g)-1,-1,-1): #这里必须遍历g而非s
            if index >=0 and g[i] <= s[index]:
                count += 1
                index -= 1
        return count

376. 摆动序列

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。

例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。

相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。

给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。

思路

本题很难想,最基础的思路是,用prevDiff和nextDiff记录当前的节点的前后diff,如果异号,则说明可以保留并且统计加1,即基础条件为if preDiff >0 and nextDiff < 0 or preDiff<0 and nextDiff > 0,然后遍历过程中prevDiff随着nextDiff修改

  • 情况一: 首尾节点的处理,首节点,假装之前还有一个和他相等的节点,那么是否统计第一个节点只看和第二个节点的关系即nextDiff,为了统一逻辑,则上面的基础条件变为 if preDiff >= 0 and nextDiff < 0 or preDiff<=0 and nextDiff > 0
  • 情况二: 非单调有平坡,可以延续情况一的逻辑
  • 情况三: 单调有平坡,将修改时机从 遍历过程中prevDiff随着nextDiff修改 改为,只有发生方向变化时,才修改prevDiff,这个很难想到
    从看完题解再分析,可以分析思路是找到需要保留的节点,因为最终形成的是摆动序列,所以最终形成的prev,diff是只记录方向变化的
class Solution376:
    def wiggleMaxLength(self, nums: List[int]) -> int: 
        if len(nums) == 1: 
            return 1
        
        preDiff = 0
        nextDiff = 0
        result = 1 # 默认最后一个为一个波动
        
        for i in range(len(nums)-1):
            nextDiff = nums[i+1] - nums[i]
            if preDiff >= 0 and nextDiff < 0 or preDiff<=0 and nextDiff > 0:
                result +=1    
                preDiff = nextDiff # 只有方向改变时才修改prediff、
        return result

53. 最大子数组和

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

思路

暴力的解法是找到每一个索引为首的最大和连续子数组,复杂度为O(n^2)。
考虑动规的解法,dp[i]表示以当前索引i为结尾的最大子数组和,那么dp[i-1]表示以索引i-1为结尾的最大子数组和,dp[i]就取包含以i-1结尾的子序列和不包含以i-1结尾的子序列两种情况中的最大值,即dp[i] = max(dp[i-1]+nums[i],nums[i])

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        dp = [0] * len(nums) # dp数组的元素: 以当前索引i结尾的最大和连续子数组的长度
        dp[0] = nums[0]
        
        for i in range(1,len(nums)):
            dp[i] = max(dp[i-1]+nums[i],nums[i])
        
        return max(dp)

贪心思路:当遍历到某个数和为负数时,则以下一个数为起点,重新累加

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        result = float("-inf")
        sum = 0 
        for i in range(len(nums)):
            sum += nums[i]
            result = sum if result<sum else result
            if sum < 0:
                sum = 0
        return result

心得体会

贪心法的思路非常灵活,且是用局部最优来尝试是否达到全局最优,其中的证明也是比较困难的,现阶段还无法严格证明,只能去模拟看是否可以通过,或无法举出反例的情况,可以锻炼一定的思维能力,想不出来可以看题解,看懂思路后编码即可,不必追求完美。本章的目标就是理解思路后的编码能力.

标签:nums,int,Day27,part1,nextDiff,数组,序列,dp,贪心
From: https://www.cnblogs.com/haohaoscnblogs/p/18354750

相关文章

  • 代码随想录day27 || 455 分饼干,376 摆动序列,53 最大子序列和
    分饼干funcfindContentChildren(g[]int,s[]int)int{ //第一思路,双指针暴力解法 varcountint varused2=make([]bool,len(s)) g=quicksort(g) s=quicksort(s) for_,child:=rangeg{ foridx,cookie:=ranges{ if!used2[idx]&&cookie>=......
  • VDI/VDE 2634 Part1 2022:05
    Optical3DmeasuringsystemsImagingsystemswithpoint-by-pointprobingPreliminarynoteOptical3Dmeasuringsystemsareusedasuniversalmeasuringandtestequipment.Ineachcase,theusermustbesurethattheoptical3Dmeasuringsysteminusecomp......
  • 贪心
    有些题dp是难做的或做不了的,这个时候可以去设计一种策略使得决策尽可能最优,也就是贪心。可以说贪心有时候是一种乱搞,但乱搞也能搞出出题人想不到的正解。反悔贪心有些题中直接dp的复杂度很高并且很难优化或者有后效性无法dp,朴素贪心考虑可以做到\(O(n)\)但是无法保证正确......
  • 贪心系列专题篇四
    目录整数替换解法一解法二俄罗斯套娃信封问题堆箱子可被三整除的最大和距离相等的条形码重构字符串声明:接下来主要使用贪心法来解决问题!!!整数替换题目思路下面将使用两种方法来解决这道题,第一种方法是递归+记忆化搜索;第二种方法是贪心。解法一使用递归+记忆......
  • APP逆向 day27unidbg打包
    一.前言上三次我们把unidbg的基础到进阶都讲完了,现在我们来讲unidbg的大打包,打包分为两种打包,一种是传参一种是不传参,我根据往期案例挑几个和大家讲二.不传递参数这个我们拿车智赢举例子2.1配置和编译点击这里 再点击这几个选项点击应用,这样就是配置好了再这么选......
  • 贪心算法-活动安排问题
    贪心算法贪心算法总是选择当前看起来最优的选择(局部最优解),希望得到的结果是一个整体最优解。但是,并非总是选择局部最优解就能够得到整体最优解,这一点需要在问题具有贪心选择性和优化子结构时才成立。贪心选择性贪心选择性:第一次做出贪心选择是正确的。优化子结构问题......
  • 「Day 2—贪心问题&分治&前缀和」
    贪心问题定义顾名思义,越贪越好。。。习题P1094[NOIP2007普及组]纪念品分组思路简单来说:最少的+最多的,利用双指针。代码#include<algorithm>#include<iostream>usingnamespacestd;intw,n;intp[30005];intmain(){cin>>w;cin>>n;for(inti=1;i......
  • 贪心·区间问题
    区间问题Whatis贪心贪心:每一次只在当前这一块选择局部最优解,但最后可以走到全局最优解,只有一个问题是单方的,才可以使用贪心算法题目Acwing.905区间选点905.区间选点-AcWing题库举例:如图,需要选两个点,每个区间都有一个点,第1、2、3个区间内有第一个点,第4个区间包......
  • 「代码随想录算法训练营」第二十八天 | 动态规划 part1
    509.斐波那契数题目链接:https://leetcode.cn/problems/fibonacci-number/题目难度:简单文章讲解:https://programmercarl.com/0509.斐波那契数.html视频讲解:https://www.bilibili.com/video/BV1f5411K7mo题目状态:过!思路:当n=0时,返回0;当n=1时,返回1;当n>=2时,返回fib(......
  • CF1883E+CF1995C-对数+贪心
    CF1883E+CF1995C对数+贪心CF1883ELookBack大致题意给你一个整数数组$a_1,a_2,…,a_n$。你需要用最少的运算次数使数组不递减。在一次操作中,您需要执行以下操作:选择一个索引\(1\leqi\leqn\)、设置$a_i=a_i⋅2$.数组\(b_1,b_2,…,b_n\)在所有$1\leqi\l......