Studying-代码随想录训练营day28| 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II、1005.K次取反后最大化的数组和

news2024/12/23 22:56:47

第28天,贪心算法part02,题目难度在增加,要锻炼贪心思维能力(ง •_•)ง,编程语言:C++

目录

122.买卖股票的最佳时机II

55. 跳跃游戏

45.跳跃游戏II

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

总结:


122.买卖股票的最佳时机II

文档讲解:代码随想录买卖股票的最佳时机II

视频讲解:手撕买卖股票的最佳时机II

题目:

学习: 本题最关键的在于理解每天价格之间的关系,事实上从第二天起每一天都会存在利润,只不过有的时候利润是负,有的时候利润是正。因此依据贪心思想,我们收集所有的正利润,得到的就会是最大的利润。不拘泥于选择哪一天买进,而是把每天都作为可能买进,可能卖出的选择,从而收割所有的正利润。

代码:

//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int result = 0; //统计利润
        //贪心思路,每次只收集正利润
        for(int i = 1; i < prices.size(); i++) {
            //贪心没有套路,只能靠多了解锻炼
            int profit = prices[i] - prices[i - 1];
            if(profit > 0) {
                result += profit;
            }
        }
        return result;
    }
};

总结:贪心没有套路,只能通过多练习题目,了解更多的题型,提高贪心的思维能力。


55. 跳跃游戏

文档讲解:代码随想录跳跃游戏

视频讲解:手撕跳跃游戏

题目:

学习:本题不能拘泥在每一步怎么跳上,因为跳跃的方法有很多种,如果关注点在跳多少,怎么跳上就会使得需要遍历的情况很多,并且数组一旦长起来,耗费的时间也会指数增加。

本题的关键在于理解并找到能够跳跃的最大长度(最大覆盖范围),从下标为0开始,我们每走一步确定当前能够到达的最大长度(局部最优),直到最大长度大于等于数组的长度说明能够到达终点,或者是我们遍历能够达到的最大长度后,还是没有达到终点则说明不能到达终点(整体最优)。用图来表示为:

下标 i 在cover范围内移动,每次我们找到了更大的cover,就进行更新。

代码:

//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:
    bool canJump(vector<int>& nums) {
        //贪心策略,找到跳跃的最大覆盖范围
        int cover = 0; //初始化覆盖范围
        for(int i = 0; i <= cover; i++) {
            //更新跳跃的最大覆盖范围
            cover = max(cover, i + nums[i]);
            //说明覆盖到了最后一个节点
            if(maxboard >= nums.size() - 1) return true;
        }
        return false;
    }
};

45.跳跃游戏II

文档讲解:代码随想录跳跃游戏II

视频讲解:手撕跳跃游戏II

题目:

学习: 本题与上一题不同的地方在于,本题需要统计走的步数,不能单纯的看覆盖的范围大小了,同时本题题干也说明了一定能够到达最后的位置。

但本题依旧需要用到每一步的覆盖范围,不同的在于,本题需要用一个变量记录前一步覆盖的范围,而遍历过程中下标i超过了覆盖范围时,就说明要走下一步了,此时前一步的覆盖范围就变成了当前的最大覆盖范围,之后依次类推直到找到覆盖范围到达最后的节点。用图来表示为:

代码:关键在于:1.如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。2.如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。

//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:
    int jump(vector<int>& nums) {
        if (nums.size() == 1) return 0;
        int result = 0; //记录跳跃的步数
        int precover = 0; //当前覆盖最远距离下标
        int cover = 0; //下一步覆盖最远距离下标
        for(int i = 0; i < nums.size(); i++) {
            cover = max(cover, i + nums[i]);
            if(i == precover) {
                result++;
                precover = cover;
                if (precover >= nums.size() - 1) {
                    return result;
                }
            }
        }
        return result;
    }
};

总结:本题的贪心依旧十分巧妙,理解本题的关键在于: 以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点,这个范围内最少步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。


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

文档讲解:代码随想录K次取反后最大化的数组和

视频讲解:手撕K次取反后最大化的数组和

题目:

学习:显然本题的贪心想法是很容易能够想到的,本题有两个贪心的部分:1.当数组中存在负数,且k大于0时,我们局部最优就是将绝对值最大的负数进行反转,这样才能够最终得到最大的数组之和。2.当数组中不存在负数后,k还大于0,此时我们局部最优的方式应该是将绝对值最小的正整数(包含0)进行反转,并且只对其进行反转,这样的话如果k为偶数,最后还是只有正整数,如果k为负数,那这个负数也会是绝对值最小的那个,最终就能得到数组和最大。

代码:根据上述贪心逻辑,我们可以写出代码如下,主要注意两点:1.要先对数组进行排序;2.要找到绝对值最小的数,包括从负数变为正数后的那些数。

//时间复杂度O(nlogn)排序算法复杂度
//空间复杂度O(1)
class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        //贪心逻辑,先对负数进行取反(先取反绝对值最小的负数)
        //如果k还有剩余,对最小的正数进行取反
        sort(nums.begin(), nums.end());
        int count = INT_MAX; //记录最小的正数,包括负数变成的正数
        int result = 0; //记录最终和
        //取反所有负数
        for (int i = 0; i < nums.size(); i++) {
            if(k > 0 && nums[i] < 0) {
                k--;
                nums[i] *= -1; 
            }
            count = min(count, nums[i]);
            result += nums[i];
        }
        //如果还有奇数次的k,把最小的正数取反,如果是偶数的k就不用了,因为可以对一个数反复取反
        if(k%2 == 1) {
            //把最小的正数取反也就意味着减去两倍的count(减去原先的count,再加上负数的count)
            result -= count*2;
        }
        return result;
    }
};

本题对于排序算法还有可以优化的部分,可以最开始就通过绝对值大小对数组进行排序。最后可以根据以下步骤进行代码编写:

  • 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K--
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
  • 第四步:求和

代码:

//时间复杂度O(nlogn)
//空间复杂度O(1)
class Solution {
static bool cmp(int a, int b) {
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& A, int K) {
        sort(A.begin(), A.end(), cmp);       // 第一步
        for (int i = 0; i < A.size(); i++) { // 第二步
            if (A[i] < 0 && K > 0) {
                A[i] *= -1;
                K--;
            }
        }
        if (K % 2 == 1) A[A.size() - 1] *= -1; // 第三步
        int result = 0;
        for (int a : A) result += a;        // 第四步
        return result;
    }
};

总结:

贪心算法,更多的还是考研一个常识性和思维性的东西,需要多加练习,多加锻炼。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

npm install puppeteer 报错 npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated解决办法

npm install puppeteer 报错如下&#xff1a; npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL instead. npm ERR! Error: ERROR: Failed to set up Chrome v126.0.6478.126! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to sk…

绝区零国际服下载 一键下载绝区零国际服教程

绝区零是一款米哈游倾情打造的全新都市幻想动作角色扮演游戏。在游戏中&#xff0c;我们将扮演一名绳匠&#xff0c;这是为出于各种原因需要进入危险空洞的人提供指引的专业人士。您将与独特的角色一起踏上冒险之旅&#xff0c;携手探索空洞&#xff0c;对战强大敌人&#xff0…

每周题解:最大半连通子图

题目链接 最大半连通子图 题目描述 一个有向图 G ( V , E ) G\left(V,E\right) G(V,E) 称为半连通的 (Semi-Connected)&#xff0c;如果满足&#xff1a; ∀ u , v ∈ V \forall u,v\in V ∀u,v∈V&#xff0c;满足 u → v u\to v u→v 或 v → u v\to u v→u&#xff0…

番外篇 | 斯坦福提出即插即用二阶优化器Sophia :相比Adam实现2倍加速,显著节省大语言模型训练成本

前言:Hello大家好,我是小哥谈。大模型的预训练成本巨大,优化算法的改进可以加快模型的训练时间并减少训练开销。目前大模型的训练优化器基本上都采用Adam及其变体,并且Adam的应用已经有9个年头了,在模型优化方面相当于霸主的地位。但是能否够在优化器方面提高模型预训练效…

【每日刷题】Day79

【每日刷题】Day79 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1619. 删除某些元素后的数组均值 - 力扣&#xff08;LeetCode&#xff09; 2. 1365. 有多少小于当前…

python3.8安装详细教程

python3.8下载及安装详细教程 Python 3.8 是一个重要的Python版本&#xff0c;它引入了一系列新功能和改进。以下是对Python 3.8的详细概述&#xff0c;包括其关键特性、安装方法以及版本状态等信息。 Python 3.8的关键特性 海象运算符&#xff08;Walrus Operator&#xff09…

保障性住房数字化运营平台助力租赁住房智能化管理

保障性住房能提供合理的价格、良好的配套设施和优越的租住体验&#xff0c;租赁将不是问题。 一、发力租赁型保障房建设 随着城镇化进程的加速和流动人口规模的扩大&#xff0c;进城务工人员、新就业大学生等新市民、青年人的住房困难问题日益凸显。加快发展租赁型保障性住房…

深圳技术大学oj C : 生成r子集

Description 输出给定序列按字典序的 &#xfffd; 组合&#xff0c;按照所有 &#xfffd; 个元素出现与否的 01 标记串 &#xfffd;&#xfffd;&#xfffd;&#xfffd;−1,...,&#xfffd;1 的字典序输出. 此处01串的字典序指&#xff1a;先输入的数字对应低位&#x…

使用高斯混合模型识别餐厅热点

使用 GMM 识别加拿大多伦多的直观餐厅集群&#xff08;附 Python 代码&#xff09; 聚类算法&#xff08;例如 GMM&#xff09;是一种有用的工具&#xff0c;可帮助识别数据中的模式。它们使我们能够识别数据集中的子组&#xff0c;从而提高你的理解或增强预测模型。在本文中&a…

中国国产AI芯片的崛起

一、CUDA的垄断 当讨论半导体行业面临的挑战时&#xff0c;你首先想到的是什么&#xff1f;光刻机&#xff1f;3纳米或者5纳米技术&#xff1f;我们无法生产的完美方形芯片&#xff1f;是的&#xff0c;但也不完全是。 人们经常把半导体芯片归类为硬件产业&#xff0c;但实际上…

mmcv安装失败及解决方案

假如想安装的版本是mmcv1.4.0, 但是pip install mmcv1.4.0总是失败&#xff0c;若是直接pip install mmcv会安装成功&#xff0c;但是安装的就是最新版本&#xff0c;后面代码跑起来还会报错&#xff0c;怎么办呢&#xff1f; 接下来分享一个mmcv指定版本安装的方式。 网页&a…

PCL小笔记

一、常用概念 1&#xff0c;过滤器Filters 消除噪音 2&#xff0c;特征Features 集合点属性&#xff1a;曲面的曲率估计和查询点的法线 通过k-neighborhood计算得到这两个属性作为特征 查找方法&#xff1a;KD-tress、八叉树等 3&#xff0c;关键点Keypoints 可以利用明确标…

ios-实验室暑假培训(1)

一 组队 在正式培训之前&#xff0c;也是数模比赛的众中之重。 一定要商讨好组队的相关事宜&#xff01;要求建模/编程/写作/写作三方能力交叉&#xff01; 而这三个当中&#xff0c;决定比赛拿奖上限的是编程手&#xff0c;决定比赛能不能拿奖的是写作手。而建模的更像是一个…

【JavaWeb】登录校验-会话技术(一)Cookie与Session

登录校验 实现登陆后才能访问后端系统页面&#xff0c;不登陆则跳转登陆页面进行登陆。 首先我们在宏观上先有一个认知&#xff1a; HTTP协议是无状态协议。即每一次请求都是独立的&#xff0c;下一次请求并不会携带上一次请求的数据。 因此当我们通过浏览器访问登录后&#…

Cyuyan中的自定义类型——结构体

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、结构体基础知识&#xff08;一&#xff09;、结构体类型的声明、变量的创建与初始化&#xff08;二&#xff09;、结构成员访问操作符&#xff08;三&#…

近红外光谱脑功能成像(fNIRS):1.光学原理、变量选取与预处理

一、朗伯-比尔定律与修正的朗伯-比尔定律 朗伯-比尔定律 是一个描述光通过溶液时被吸收的规律。想象你有一杯有色液体&#xff0c;比如一杯红茶。当你用一束光照射这杯液体时&#xff0c;光的一部分会被液体吸收&#xff0c;导致透过液体的光变弱。朗伯-比尔定律告诉我们&#…

如何在主动动态安全中使用人工智能驱动的威胁分类提高防御精准度

面对当今世界不断演变的网络威胁&#xff0c;人工智能和网络安全将会发挥重要的防护作用。在数据泄露和网络攻击日益突出的时代&#xff0c;人工智能和网络安全之间的合作成为数字安全战场上的强大盟友。 本文将深入研究这两个领域的融合&#xff0c;揭示它们在彻底改变威胁检测…

未来的钥匙在于过去:学历史的真正意义,震惊!历史竟然是偶然的?从历史中寻找未来的方向!

我们自幼接受的教育是&#xff0c;学历史是为了相信历史是必然的。中国人民必然战胜日寇的侵略&#xff0c;解放思想和改革开放必定会发生&#xff0c;和平和发展必定是世界的主题&#xff0c;中国经济必定是高速增长…… 然而&#xff0c;在真正的历史学家眼中&#xff0c;历史…

什么是 Socks5 代理?了解和使用 SOCKS5 代理的终极指南

SOCKS5是什么以及它如何工作&#xff1f; 在网络和互联网协议领域&#xff0c;有多种工具和技术在确保安全高效的通信方面发挥着至关重要的作用。 SOCKS5 就是这样一个工具&#xff0c;它代表套接字安全版本 5。 在这篇博文中&#xff0c;我们将深入探讨 SOCKS5 的细节&…

实战项目——用Java实现图书管理系统

前言 首先既然是管理系统&#xff0c;那咱们就要实现以下这几个功能了--> 分析 1.首先是用户分为两种&#xff0c;一个是管理员&#xff0c;另一个是普通用户&#xff0c;既如此&#xff0c;可以定义一个用户类&#xff08;user&#xff09;&#xff0c;在定义管理员类&am…