算法刷题Day31 | 455.分发饼干、376. 摆动序列、53. 最大子数组和

目录

  • 0 引言
  • 1 分发饼干
    • 1.1 我的解题
    • 1.2 更好的解题
  • 2 摆动序列
    • 2.1 我的解题
    • 2.2 我的错误原因(GPT分析)
    • 2.3 改进
  • 3 最大子数组和
    • 3.1 我的解题

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:算法专栏
  • 💥 标题:算法刷题Day31 | 455.分发饼干、376. 摆动序列、53. 最大子序和
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

0 引言

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

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

这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。
做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。

1 分发饼干

  • 🎈 文档讲解
  • 🎈 视频讲解
  • 🎈 做题状态:

1.1 我的解题

我的想法,遍历饼干,然后再从大到小遍历孩子的胃口。找到刚好匹配的数就结果加一,然后把这个胃口数据移除。

#include <algorithm>

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int count = 0;

        // 先将数组排序
        sort(g.begin(), g.end());
        sort(s.begin(), s.begin());

        // 初步思考,使用两层循环遍历,先遍历饼干,再遍历胃口
        for (int i = 0; i < s.size(); i++)
        {
            for (int j = g.size()-1; j >= 0; j--)
            {
                if (s[i] < g[j])
                {
                    continue;
                }
                else
                {
                    count++;
                    g.erase(g.begin() + j);
                    break;
                }
            }
        }

        return count;
    }
};

1.2 更好的解题

只用了一个循环模拟了胃口和饼干的同时遍历。
先遍历大饼干,先满足胃口大的小孩。

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int index = s.size() - 1; // 饼干数组的下标
        int result = 0;
        for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口
            if (index >= 0 && s[index] >= g[i]) { // 遍历饼干
                result++;
                index--;
            }
        }
        return result;
    }
};

2 摆动序列

  • 🎈 文档讲解
  • 🎈 视频讲解
  • 🎈 做题状态:

2.1 我的解题

其实本题只需要画图搞清楚一个条件即可,一定要取极大值作为转折点。这样摆动的序列才是最长的。然后本题还有个比较麻烦的地方是平坡,也就是相邻点的值相等。这样也不好判断。为了便于理解,可以先遍历一遍数组将相同的点去除,然后再求解。这样就简单很多。
当然也可以通过条件判断的方式不记录平坡,然后判断非平坡情况下是否为满足条件。

本题难点:
是求的子序列,子序列的话是可以从原始序列中删除元素的。所以比较难判断。

下面是我的错误代码。

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() == 1) return 1;
        if (nums.size() == 2 && nums[0] != nums[1]) return 2;

        int count = 2;
        int maxCount = count;
        // 此时数组个数大于等于3
        for (int i = 2; i < nums.size(); i++)
        {
            int diff1 = nums[i] - nums[i-1];
            int diff2 = nums[i-1] - nums[i-2];
            // cout << "diff1 = " << diff1 << endl;
            // cout << "diff2 = " << diff2 << endl;
            if ((diff > 0 && prevDiff < 0) || (diff < 0 && prevDiff > 0))
            {
                if (diff1 != 0 && diff2 != 0)
                {
                    count++;
                }
            }
            else
            {
                // 如果不满足则count重置为2,同时将不满足的数给删除
                //count = 2;
                nums.erase(nums.begin() + i - 1);
                i--;
            }
            maxCount = max(maxCount, count);
            cout << "count = " << count << endl;
        }

        return maxCount;
    }
};

2.2 我的错误原因(GPT分析)

您的代码试图解决的问题是寻找给定数组中最长的摆动子序列的长度。摆动序列被定义为序列中的数字交替大于和小于其前一个数字。您的实现逻辑有几个关键的缺陷和改进点:

  1. 数组修改: 您尝试通过删除不符合摆动序列条件的元素来维护摆动序列,这不仅改变了原数组,而且并不是解决这个问题的有效方法。在寻找最长摆动序列时,我们并不需要修改原数组,而是应该寻找一种方式来识别摆动序列的长度而不实际改变数组内容。

  2. 摆动序列的识别: 您的逻辑试图通过比较当前元素与前两个元素的差来确定是否构成摆动。虽然这种思路基本正确,但其实现方式过于复杂,且erase操作导致时间复杂度增加。此外,您的条件检查(diff1 == abs(diff1) && diff2 == -abs(diff2) || diff2 == abs(diff2) && diff1 == -abs(diff1))可以简化为检查diff1diff2的符号是否相反。

  3. 初始化问题: 初始的count设置为2是基于至少存在一对不同的元素。如果数组开始就有连续相等的元素,这种初始化是不准确的。

为了改进您的代码,可以采取以下策略:

  • 初始化时考虑特殊情况: 首先处理只有一个元素或所有元素都相等的情况。
  • 使用状态变量: 记录最后一次摆动是上升还是下降,而不是每次都检查三个元素。
  • 避免修改原数组: 直接通过遍历原数组来判断每一步是否构成摆动,不需要修改原数组。

下面是一个改进后的实现示例:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        if (n < 2) return n;
        
        // 初始化计数器和方向
        int count = 1; // 至少有一个元素,所以从1开始计数
        int prevDiff = 0;
        
        for (int i = 1; i < n; ++i) {
            int diff = nums[i] - nums[i-1];
            if ((diff > 0 && prevDiff <= 0) || (diff < 0 && prevDiff >= 0)) {
                // 发现摆动,增加计数并更新prevDiff
                count++;
                prevDiff = diff;
            }
        }
        
        return count;
    }
};

这个实现不修改原数组,通过遍历数组一次,比较相邻元素之差来判断摆动,并且只在摆动方向发生变化时增加计数器。这种方式更为简洁且效率更高。

2.3 改进

不能将峰值删除,相当于求极值点有几个。看了视频发现有平坡的情况需要很多特殊讨论,那么可不可以直接把数据的平坡给去除呢?然后再来做题。使用遍历把相邻相同的数据给去除。

3 最大子数组和

  • 🎈 文档讲解
  • 🎈 视频讲解
  • 🎈 做题状态:

3.1 我的解题

首先明确思路:
最大和的子数组,然后每次移动记录数组和,如果遇到sum小于0,则可以直接将sum置为0,然后从后面遇到的第一个正数开始记录。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = nums[0];
        int sum = 0;
        for (int i = 0; i < nums.size(); i++)
        {
            sum += nums[i];
            result = max(result, sum);
            if (sum <= 0)
            {
                sum = 0;
            }
        }
        return result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/536589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫实战:我国城市的地铁数据以及分析

文章目录 1 引言2 项目背景3 技术栈和工具选择4 数据爬取4.1 爬虫设计4.2 代码实现4.3 数据保存4.4 关键点分析 5 数据处理与分析5.1 数据清洗5.2 数据分析5.3 关键点分析 6 完整代码以及结果展示7 小分享 1 引言 本文将指导你如何通过Python从高德地图爬取中国城市地铁站数据…

5G-A有何能耐?5G-A三载波聚合技术介绍

2024年被称作5G-A元年。5G-A作为5G下一阶段的演进技术&#xff0c;到底有何能耐呢&#xff1f; 三载波聚合&#xff08;3CC&#xff09;被认为是首个大规模商用的5G-A技术&#xff0c;将带来手机网速的大幅提升。 █ 什么是3CC 3CC&#xff0c;全称叫3 Component Carriers…

前端js基础知识(八股文大全)

一、js的数据类型 值类型(基本类型)&#xff1a;数字(Number)、字符串&#xff08;String&#xff09;、布尔(Boolean)、对空&#xff08;Null&#xff09;、未定义&#xff08;Undefined&#xff09;、Symbol,大数值类型(BigInt) 引用数据类型&#xff1a;对象(Object)、数组…

HNUST湖南科技大学嵌入式开发板使用-2024

目录 1.需要准备的软件(版本必须相同)꒰ঌ( ⌯ ⌯)໒꒱ 2.下载链接地址⌯▾⌯ 3.软件安装教程 4.安装好了&#xff0c;正常情况会是什么样子呢&#xff1f;(๑•̌.•๑) 4.1.拆入第一个接口(串口com接口是用来上传代码的ฅ˙Ⱉ˙ฅ) 4.2.拆入第三个接口&#xff08;SWD Jlink口…

android android.permission.MANAGE_EXTERNAL_STORAGE使用

android11 及以上版本&#xff0c;如果release版本要读取外部存储公共目录&#xff0c;即sdcard公共目录&#xff0c;需要在androidManifest.xml下申明 <uses-permission android:name"android.permission.MANAGE_EXTERNAL_STORAGE" /> 如果要发版到海外&…

数据资产与数据要素的重要性及数据资产入表的实践指南

## 引言在当今快速发展的数字化时代&#xff0c;数据资产已经成为企业最宝贵的资源之一。数据资产不仅对企业的运营决策有着至关重要的影响&#xff0c;而且在企业的财务健康和市场竞争力方面扮演着核心角色。数据要素&#xff0c;作为构成数据资产的基本单元&#xff0c;其管理…

Centos Docker Oracle11g 密码过期修改

症状&#xff1a; Centos Oracle11g环境变量配置 如果没有配置环境变量&#xff0c;需要先配置Oracle环境变量&#xff0c;否则执行sqlplus时会提示&#xff1a;SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory 配置方法&#xff1a; 第一步&a…

C++ 2024-4-2 作业

1.模板类实现顺序栈 #include <iostream> #define MAX 8 using namespace std; template<typename T> class stack {T data[MAX];int top; public:stack():top(-1){}bool empty_stack();bool full_stack();void push_stack(T data);void pop_stack();void show();…

定长子串中元音的最大数目

题目链接 定长子串中元音的最大数目 题目描述 注意点 s 由小写英文字母组成返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数1 < k < s.length 解答思路 根据滑动窗口的思想&#xff0c;维持一个大小为k的窗口&#xff0c;每次移动窗口时整体向右…

【ROS2笔记三】构建ROS2功能包

3.构建ROS2功能包 文章目录 3.构建ROS2功能包3.1ROS2中包的组成部分3.2创建ROS2功能包并编写节点3.2.1使用CMake创建功能包3.2.2编写cpp节点代码 3.3编译运行节点3.4使用面向对象的方式编写ROS2节点3.5使用RCLPY编写节点Reference 3.1ROS2中包的组成部分 ROS2可以使用CMake或者…

用于显著提高检索速度和降低成本的二进制和标量嵌入量化

我们引入了嵌入量化的概念&#xff0c;并展示了它们对检索速度、内存使用、磁盘空间和成本的影响。我们将讨论理论上和实践中如何对嵌入进行量化&#xff0c;然后介绍一个 演示&#xff0c;展示了 4100 万维基百科文本的真实检索场景。 演示地址https://hf.co/spaces/sentence-…

C语言——贪吃蛇小游戏

目录 前言 一、贪吃蛇游戏 1.1 游戏背景 1.2 游戏功能 1.3 技术要点 二、Win32 API 2.1 控制台程序 2.2 控制台屏幕上的坐标COORD 2.3 GetStdHandle 2.4 GetConsoleCursorInfo 2.4 CONSOLE_CURSOR_INFO 2.5 SetConsoleCursorInfo 2.6 SetConsoleCursorPosition …

第十届蓝桥杯省赛真题(C/C++大学B组)

试题 A: 组队 答案&#xff1a;490 试题 B: 年号字串 #include <bits/stdc.h> using namespace std;int main() {//26进制数 int n;cin>>n;string s "111";for(int i s.length() - 1;i >0;i--){s[i] A - 1 n % 26;n / 26;}cout<<s<<…

交换机与路由器缓冲区:寻找完美大小

*本文系SDNLAB编译自瞻博网络技术专家兼高级工程总监Sharada Yeluri领英 在路由器和交换机中&#xff0c;缓冲区至关重要&#xff0c;可以防止网络拥塞期间的数据丢失。缓冲区到底要多大&#xff1f;这个问题在学术界和工业界一直备受争议。本文探讨了高端路由器中数据包缓冲的…

Matlab 实时读取串口并绘图

Matlab 实时读取串口并绘图 Vofa Vofa 是一个很好的跨平台上位机软件&#xff0c;但是它无法保存数据&#xff0c;而且作者也并没有要继续更新的意思&#xff0c;保存数据功能应该是遥遥无期了。因此本文使用 Matlab 实时读取串口数据&#xff0c;并使用 plot 函数绘制。 vo…

性能分析-nginx(tomcat、nginx【配置】、负载均衡)

tomcat 像kyj项目请求直接对接 tomcat&#xff0c;tomcat的连接池就会直接影响“并发用户数” 如果这种情况下做性能测试的时候&#xff0c;并发用户数不能满足要求&#xff0c;可以适当加大线程池的配置。 如&#xff1a;项目性能测试发现项目所在机器&#xff0c;资源利用率…

hexo接入github Discussions评论系统

评论存储仓 可以是你的博客项目的(github)仓库&#xff0c;也可以单独新建一个评论存储仓库。 我的博客项目在gitee上&#xff0c;就以新建存储仓为例&#xff1a; 使用Discussions评论系统必须开通Discussions模块&#xff01; 安装giscus插件 https://github.com/apps/…

书客、月影、欧普护眼大路灯哪款好?三款落地灯真实对比测评

作为在照明电器领域资深的评测员&#xff0c;我对市面上各种新颖的照明家电有着深入的探索和研究。大路灯能够提供舒适健康的照明光线&#xff0c;目前正受到许多用眼人群的广泛欢迎。&#xff0c;当然随着大路灯的普及&#xff0c;市场中也充斥着一些低劣的大路灯产品&#xf…

中国平安金融壹账通交付管理中心总经理崔羽先生受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 中国平安金融壹账通交付管理中心总经理崔羽先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“项目管理成与败&#xff0c;人才是第一要素”。大会将于5月25-26日在北京举办&#xff0c;敬请关注&#xff01; 议题简要…

消息队列之-----------------zookeeper机制

目录 一、ZooKeeper是什么 二、ZooKeeper的工作机制 三、ZooKeeper特点 四、ZooKeeper数据结构 五、ZooKeeper应用场景 5.1统一命名服务 5.2统一配置管理 5.3统一集群管理 5.4服务器动态上下线 5.5软负载均衡 六、ZooKeeper的选举机制 6.1第一次启动选举机制 6.2非…