第三十三天| 1005.K次取反后最大化的数组和、134. 加油站 、135. 分发糖果

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

题目链接:1005 K次取反后最大化的数组和

题干:给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组 可能的最大和 。

思考:两次贪心法。首先处理负数,局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。在数组全为正数且转换次数还剩的情况下,局部最优:只找数值最小的正整数进行反转,当前数值和可以达到最大,全局最优:整个 数组和 达到最大。

本题的解题步骤为:

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

代码:

class Solution {
public:
    static int cmp(int a, int b) {        //按绝对值比较
        return abs(a) > abs(b);
    }

    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end(), cmp);        //排序
        int count = k;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] < 0 && count > 0) {     //转换次数够的情况下负数取反
                nums[i] *= -1;
                count--;
            }
        }
        if (count % 2 == 1)     //剩余次数为奇数转换绝对值最小的正数
            nums[nums.size() - 1] *= -1;        
        
        int result = 0;
        for (int m : nums)
            result += m;
        return result;
    }
};

Leetcode 134. 加油站

题目链接:134 加油站

题干:在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

思考一:暴力法。遍历每一个加油站为起点的情况,模拟一圈。如果跑了一圈,中途没有断油,而且最后油量大于等于0,说明这个起点是ok的。(超时)

代码:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        for (int i = 0; i < gas.size(); i++) {
            int remainder = gas[i] - cost[i];       //到达下一站的剩余油量
            int index = (i + 1) % gas.size();       //到达的下一站
            while (remainder > 0 && index != i) {       //寻找能到达的最远站(remainder等于0无法保证答案唯一)
                remainder += gas[index] - cost[index];
                index = (index + 1) % gas.size();
            }
            if (remainder >= 0 && index == i)    return i;      //以i为起点跑了一圈
        }
        return -1;
    }
};

思考二:贪心法。如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量remainder[i]相加一定是大于等于零的。那么让i从0开始累加remainder[i],和记为curRemainder,一旦curRemainder小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curRemainder。

  • 这里可能存在一个疑惑:为什么curRemainder小于零起始位置就从i+1算起,而不是从[0, i]中间节点算起。

如果 curRemainder<0 说明 区间和1 + 区间和2 < 0, 那么 假设从上图中的位置开始计数curRemainder不会小于0的话,就是 区间和2>0。区间和1 + 区间和2 < 0 同时 区间和2>0,只能说明区间和1 < 0, 那么就会从假设的箭头初就开始从新选择其实位置了。

当然遍历过程要统计总加油量和耗油量,如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的。

代码:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int curRemnant = 0;     //记录当前剩余油量
        int totalRemnant = 0;       //记录转一圈后剩余油量
        int start = 0;      //记录出发点
        for (int i = 0; i < gas.size(); i++) {
            curRemnant += gas[i] - cost[i];
            totalRemnant += gas[i] - cost[i];
            if (curRemnant < 0) {       //start为起始节点失败
                 curRemnant = 0;
                 start = i + 1;
            }
        }
        if (totalRemnant < 0)   return -1;      //跑完一圈累计油量为负则无法跑完
        return start;
    }
};

思考三:直接从全局进行贪心选择,情况如下:

  • 情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的

  • 情况二:gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。

  • 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。

代码:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int remainder = 0;
        int min = INT_MAX;      //记录最小累计加油量与累计油耗的差

        for (int i = 0; i < gas.size(); i++) {
            remainder += gas[i] - cost[i];
            if (remainder < min)
                min = remainder;
        }

        if (remainder < 0) return -1;   //总油耗大于总加油量
        if (min >= 0)   return 0;       //0作为起始点经过中间站不存在油量不足的情况

        for (int i = gas.size() - 1; i > 0; i--) {      //从后往前寻找弥补最小差
            min += gas[i] - cost[i];
            if (min >= 0)
                return i;
        }
        return -1;
    }
};

Leetcode 135. 分发糖果

题目链接:135 分发糖果

题干:n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

思考:贪心法。此题同时考虑左右两边情况较难处理。因此将确定一边之后,再确定另一边。

  • 先确定右边评分大于左边的情况(也就是从前向后遍历)

此时局部最优:只要右边评分比左边大,右边的孩子就多一个糖果,全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果

  • 再确定左孩子大于右孩子的情况(从后向前遍历)

此时局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。

代码:

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> vec(ratings.size(), 1);
        //从前往后 确定右孩子大于左孩子的情况
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1])
                vec[i] = vec[i - 1] + 1;
        }

        //从后往前 确定左孩子大于右孩子的情况
        for (int i = ratings.size() - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1])
                vec[i] = max(vec[i], vec[i + 1] + 1);
        }

        int result = 0;
        for (int m : vec)       //统计糖果数目
            result += m;
        return result;
    }
};

自我总结:

  • 贪心法考虑分步处理以及合并思考

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

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

相关文章

博途PLC数值积分器(矩形梯形积分自由切换)

数值积分器的相关介绍,大家可以也可以参看下面几篇文章,链接如下: PLC算法系列数值积分器 https://rxxw-control.blog.csdn.net/article/details/128562853https://rxxw-control.blog.csdn.net/article/details/128562853SMART PLC 梯形和矩形积分 https://rxxw-control.…

C语言学习day16:二维数组

二维数组格式&#xff1a; 数据类型 数组名[行][列] { {值1&#xff0c;值2}, {值3&#xff0c;值4} } 代码&#xff1a; int arr[2][3] { {1,2,3},{4,5,6} }; 那么我们怎么找它的下标呢&#xff0c;我先上一副图&#xff1a; 假如我现在要找1&#xff0c;那么它…

数据结构~二叉树(基础知识)

上一篇博客我们对树有了初步了解与学习&#xff0c;这篇我将初步学习二叉树&#xff01;&#xff01;&#xff08;新年快乐&#xff01;&#xff09; 目录 二叉树 1、定义&#xff1a; 2、特点&#xff1a; 3、基本形态&#xff1a; 4、二叉树的种类&#xff1a; &…

skimage库简介

scikit-image 是专注于图像处理的Python包&#xff0c;全称是scikit-image SciKit。该包由python语言编写&#xff0c;由scipy 社区开发和维护&#xff0c;使用原生的Numpy数组作为图像对象。 一、skimage简介 skimage&#xff08;scikit-Image&#xff09;是基于python开发的…

六、Spring/Spring Boot整合ActiveMQ

Spring/Spring Boot整合ActiveMQ 一、Spring整合ActiveMQ1.pom.xml2.Queue - 队列2.1 applicationContext.xml2.2 生产者2.3 消费者 3.Topic - 主题3.1 applicationContext.xml3.2 生产者3.3 消费者 4.消费者 - 监听器4.1 编写监听器类4.2 配置监听器4.3 生产者消费者一体 二、…

【无标题】管理kvm 虚拟机

管理kvm 虚拟机 点击虚拟机 创建新的虚拟机 安装操作系统 设置root密码

mpack简明教程

文章目录 摘要MessagePack简介MPACK的简单使用在定长的buffer存储不定长的数据读取截断的数据 摘要 本文先简单介绍MessagePack的基本概念。 然后&#xff0c;介绍一个MessagePack C API - MPack的通常使用。 接着尝试对MPack截断数据的读取。 注&#xff1a;本文完整代码见…

【自然语言处理】实验3,文本情感分析

清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 代码和报告均为本人自己实现&#xff08;实验满分&#xff09;&#xff0c;只展示主要任务实验结果&#xff0c;如果需要详细的实验报告或者代码可以私聊博主 有任何疑问或者问题&#xff0c;也欢…

会声会影2024新功能及剪辑视频步骤教程

会声会影2024的新功能主要包括&#xff1a; 全新的标题动态与特效&#xff1a;用户可以为文字标题指定进入、中场和退出的不同动态效果&#xff0c;比如闪现进入、中场弹跳和淡出退出等&#xff0c;让文字标题更具动感。此外&#xff0c;还新增了多个标题特效&#xff0c;包括…

Unity中关于ScrollRect组件完整解决方案(ScrollRect中元素自动排版+ScrollRect中元素自动定位到Viewport可见范围内)

一、元素自动排版功能 1、首先要往我们的unity项目中导入两个脚本文件&#xff0c;脚本文件名称分别是UIScrollEventListener和CZScrollRect&#xff0c;这两个脚本文件代码如下所示。 1-1、介绍UIScrollEventListener脚本写法。 using System.Collections; using System.Co…

代码随想录day24--回溯的应用3

LeetCode93.修复IP地址 题目描述&#xff1a; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是…

安装luajit及使用python运行lua脚本

使用Python运行lua脚本前&#xff0c;需要先安装LuaJIT&#xff0c;LuaJIT的官网是下载 (luajit.org) 目前已不再使用.exe文件的下载方式&#xff0c;需要使用Git从公共仓库下载源码&#xff0c;git命令为&#xff1a; $ git clone https://luajit.org/git/luajit.git 下载后…

Open CASCADE学习|布尔运算

目录 1、加法&#xff1a;BRepAlgoAPI_Fuse 2、减法&#xff1a;BRepAlgoAPI_Cut 3、交集&#xff1a;BRepAlgoAPI_Common 4、交线&#xff1a;BRepAlgoAPI_Section 1、加法&#xff1a;BRepAlgoAPI_Fuse #include <gp_Pnt.hxx>#include <BRepPrimAPI_MakeBox.hxx…

云计算基础 -NUMA

UMA UMA中文翻译叫&#xff1a;一致性内存访问 多个CPU通过同一根前端总线&#xff08;FSB&#xff09;来访问内存&#xff08;所有的内存访问都需要通过北桥芯片来完成&#xff09;&#xff0c;若多个CPU访问内存的不同内存单元还是相同内存单元&#xff0c;同一时刻&#x…

Vuex核心知识整理

目录 1 搭建vuex环境 2 求和案例 3 getters 配置项 4 mapState 和 mapGetters 5 mapMutations 和 mapActions 6 Vuex 模块化 1 搭建vuex环境 vuex工作原理图&#xff08;摘自官网&#xff09; 什么时候使用Vuex&#xff1a; 1.当多个组件依赖于统一状态 2.来自不同组件…

2.15日学习打卡----初学Zookeeper(二)

2.15日学习打卡 目录: 2.15日学习打卡一. Zookeeper部署运行伪集群安装集群安装服务管理 二. Zookeeper系统模型数据模型节点特性客户端命令行节点数据信息Watcher监听机制权限控制 ACL 三. 原生api操作Zookeeper四. zkclient库操作Zookeeper五. Apache Curator操作Zookeeper六…

不同的AI修改同一篇文章标题

提问AI 我写了一篇文章&#xff0c;请帮我把标题重新改一下&#xff1a;“比较不同AI分析同一个错误代码及给出解决方案的能力&#xff08;结果出我意料&#xff09;” 这篇文章的原地址为&#xff1a;https://blog.csdn.net/snans/article/details/136132211 答案对比结果&am…

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?<= , (?= , (?<! , (?!

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?< , (? , (?<! , (?! 有好多种称呼 (?< , (? , (?<! , (?! 有好多种称呼 , 我称为: 左限定, 右限定, 左否定, 右否定 (?<左限定)    (?右限定)(?<!左否定)    (?!右限定) 再…

Linux|centos7下的编译|ffmpeg的二进制安装

Windows版本的ffmpeg&#xff1a; ###注意&#xff0c;高版本可能必须要windows10以及以上才支持&#xff0c;win7估计是用不了的 下载地址&#xff1a;Builds - CODEX FFMPEG gyan.dev 或者这个下载地址&#xff1a;https://github.com/BtbN/FFmpeg-Builds/releases 这两个…

C++面试宝典第28题:寻找丢失的数字

题目 给定一个包含n个整数的数组nums,其中nums[i]在区间[1, n]内。请找出所有在[1, n]范围内,但没有出现在nums中的数字,并以数组的形式返回结果。 示例1: 输入:nums = [4, 3, 2, 7, 8, 2, 3, 1] 输出:[5, 6] 示例2: 输入:nums = [1, 1] 输出:[2] 解析 初看这道题,…
最新文章