IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 代码随想录31——贪心:贪心算法理论基础、455分发饼干、376摆动序列 -> 正文阅读

[数据结构与算法]代码随想录31——贪心:贪心算法理论基础、455分发饼干、376摆动序列

1.贪心算法理论基础

参考:代码随想录,贪心算法理论基础

1.1.题目分类

在这里插入图片描述

1.2.贪心算法

1.2.1.什么是贪心算法

贪心的本质是选择每一阶段的局部最优,从而达到全局最优

这么说有点抽象,来举一个例子:例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?

指定每次拿最大的,最终结果就是拿走最大数额的钱。每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优

再举一个例子如果是 有一堆盒子,你有一个背包体积为n,如何把背包尽可能装满,如果还每次选最大的盒子,就不行了。这时候就需要动态规划。动态规划的问题在下一个系列会详细讲解。

1.2.2.贪心的套路(什么时候用贪心)

很多同学做贪心的题目的时候,想不出来是贪心,想知道有没有什么套路可以一看就看出来是贪心。

说实话贪心算法并没有固定的套路。所以唯一的难点就是如何通过局部最优,推出整体最优

那么如何能看出局部最优是否能推出整体最优呢?有没有什么固定策略或者套路呢?

不好意思,也没有! 靠自己手动模拟,如果模拟可行,就可以试一试贪心策略,如果不可行,可能需要动态规划。

有同学问了如何验证可不可以用贪心算法呢?

最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧

所以这也是为什么很多同学通过(accept)了贪心的题目,但都不知道自己用了贪心算法,因为贪心有时候就是常识性的推导,所以会认为本应该就这么做

1.2.3.贪心一般解题步骤

贪心算法一般分为如下四步:

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解

其实这个分的有点细了,真正做题的时候很难分出这么详细的解题步骤,可能就是因为贪心的题目往往还和其他方面的知识混在一起

贪心没有套路,说白了就是常识性推导加上举反例。最后给出贪心的一般解题步骤,大家可以发现这个解题步骤也是比较抽象的,不像是二叉树,回溯算法,给出了那么具体的解题套路和模板。

2.455分发饼干

参考:代码随想录,455分发饼干力扣题目链接

2.1.题目

在这里插入图片描述

2.2.解答

为了满足更多的小孩,就不要造成饼干尺寸的浪费。即未给孩子的饼干,应该是满足它的胃口的饼干中最小的那个。

所以这里的局部最优就是从小饼干开始遍历,然后一旦找到可以满足胃口的孩子,就把这个小饼干喂给这个孩子。因此需要先把孩子胃口和饼干大小都进行升序排列。

代码如下所示,非常假单:

int findContentChildren(vector<int> &g, vector<int> &s)
{
    // 注意必须要先排序
    sort(g.begin(), g.end());
    sort(s.begin(), s.end());

    int index = 0;
    for(int i = 0; i < s.size(); i++)
    {
        // 首先index < g.size()保证还有没喂的孩子,防止饼干个数过多,超过孩子总数
        // 遍历所有饼干,只要当前饼干可以喂饱当前孩子,就使用这个饼干;然后继续遍历下一个饼干,喂下一个孩子
        if(index < g.size() && g[index] <= s[i])
            index++;
    }

    return index;
}

3.376摆动序列 思路不是很清晰

参考:代码随想录,376摆动序列力扣题目链接

3.1.题目

在这里插入图片描述

3.2.解答

这道题目其实就是在找符合条件的每一个小的坡度。比如上一次是在上升,那么这一次就必须下降。把上升和下降的各个峰值点连接起来,峰值点的个数就是摆动数组的长度。如下图所示:

在这里插入图片描述
给出代码如下,还不是很清晰,这个是自己写的,跟代码随想录中有点不一样。

下面代码的思路是先找到第一个有坡度的两个山峰,比如上图的1->17。此时把这个坡度给1,认为每一条线条(每一个坡度)都是属于它的前一个点的。

找到第一个有坡度的山峰之后,我们就有了上一个坡度pre_diff。然后遍历后面的点,开始寻找和上一次的坡度不同的坡度。直到找完所有的山峰。

最后,由于我们统计的是坡度,而每个坡度认为属于它连接的前面的山峰,所以山峰个数 = 坡度个数 + 1。

int wiggleMaxLength(vector<int> &nums)
{
    if(nums.size() < 2)
        return nums.size();
    
    // 先找第一个峰值
    int left = 0;
    int pre_diff = 0; // 前一个坡度
    int result = 0;   // 统计的坡度个数

    while(left < nums.size() - 1)
    {
        if(nums[left] != nums[left+1])
        {
            pre_diff = nums[left + 1] - nums[left];
            result = 1;
            break;
        }
        left++;
    }

    // 再找后面的峰值
    while(left < nums.size() - 1)
    {
        int cur_diff = nums[left + 1] - nums[left];
        if((cur_diff > 0 && pre_diff < 0) || (cur_diff < 0 && pre_diff > 0))
        {
            result++;
            pre_diff = cur_diff;
        }
        left++;
    }

    return result + 1;   // 山峰个数 = 坡度个数 + 1
    
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:39:02  更:2022-10-22 21:39:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:54:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码