刷题之贪心3

前言

大家好,我是jiantaoyab,这篇文章将给大家介绍贪心算法和贪心算法题目的练习和解析,贪心算法的本质就是每一个阶段都是局部最优,从而实现全局最优。加上这篇文章一共有30道贪心题目了,加油!

坏了的计算器

image-20240323084010973

题目分析

image-20240323090707048

所以,只要tar<= sV,无论是奇数还是偶数都加1,当tar>sV时,奇数+1,偶数/2。

代码

class Solution {
public:
    int brokenCalc(int startValue, int target) {
      int count = 0;
      while(target > startValue)
      {
  
        if(target % 2 == 0) target /= 2;
        else target += 1;
        count++;
      }
      //剩下target <= startValue 都是+1的
      //所以startValue - target 统计出有多少个1
      return count + startValue - target;
    }
};

合并区间

image-20240323091948868

题目分析

这种问题叫区间问题,一般先排序。这里用左端点排序。

image-20240323095428846

证明:能够合并的区间都是连续的

image-20240323100506949

代码

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
      vector<vector<int>> ret;
      //排序
      sort(intervals.begin(), intervals.end());
      int left = intervals[0][0], right = intervals[0][1];
      for(int i = 0; i < intervals.size(); i++)
      {
        int l = intervals[i][0], r = intervals[i][1];
        if(l <= right)
        {
          //有重叠部分
          right = max(right, r);
        }
        else
        {
          //没有重叠部分
          ret.push_back({left, right});
          left = l;
          right = r;
        }
      }
      ret.push_back({left, right});
      return ret;

    }
};

无重叠区间

image-20240323100619988

贪心的策略如果有重叠区间就移除右断点大的区间,如果没重叠区间的话说明这个区间不会和后面的区间重叠就保留下来,接着用下一个区间去和后面的区间判断。

代码

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int count = 0;
        sort(intervals.begin(), intervals.end());
        int left = intervals[0][0], right = intervals[0][1];
        for(int i = 1; i < intervals.size(); i++)
        {
          int l = intervals[i][0], r = intervals[i][1];
          if(l < right) 
          {
            //有重叠部分
            count++;
            right = min(right, r);
            
          }
          else  
          {
            //没有重叠部分
            right = r;
          }
        }
        return count;
    }
};

用最少数量的箭引爆气球

image-20240325084609342

题目分析

这道题目和合并区间求的不一样,我们这里求的是交集。

image-20240325091858577

代码

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(), points.end());
        int n = points.size();
        int ret = 1; //默认是有一个区间去和下一个区间进行比较
        int right = points[0][1];
        for(int i = 0; i < n; i++)
        {
          int l = points[i][0], r = points[i][1];
          if(l <= right)
          {
            //有交集
            right = min(r, right);
          }
          else
          {
            //没有交集
            ret++;
            right = r;
          }
        }
        return ret;
      
    }
};

整数替换

image-20240325092631599

题目分析

image-20240325102306024

代码

贪心思想来做

class Solution {
public:
    int integerReplacement(int n) {
      int count = 0;
      while(n != 1)
      {
        if(n % 2 == 0) 
        {
          n /= 2;
          count++;
        }
        else
        {
          if(n == 3)
          {
              n = 1;
              count += 2;
          }         
          else if(n % 4 == 3) //说明是...11
          {
             n = n / 2 + 1;
             count += 2;
          }
          else //....01
          {
            count += 2;
            n /= 2;
          }

        }
      }
      return count;
    }
};

用记忆化搜索做

class Solution {
  unordered_map<int, int> hash;
public:
    int dfs(long long n)
    {
      if(hash[n]) return hash[n];
      if(n == 1)
      {
        hash[1] = 0;
        return 0;
      } 
      if(n % 2 == 0)
      {
        hash[n] = 1 + dfs(n / 2);
        return hash[n];
      }
      else
      {
        hash[n] = 1 + min(dfs(n + 1), dfs(n - 1));
        return hash[n];
      }
    }
    int integerReplacement(int n) {
      return dfs(n);
    }
};

俄罗斯套娃信封问题

image-20240325103044807

题目分析

image-20240325110947735

代码

不是很理解的可以看看第一篇贪心算法

class Solution {
public:
    int maxEnvelopes(vector<vector<int>>& envelopes) {
        sort(envelopes.begin(), envelopes.end(), [&](const vector<int>&v1, const vector<int>&v2)
        {
          return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] >  v2[1];
        });

        vector<int> ret;
        ret.push_back(envelopes[0][1]);

        for(int i = 1; i < envelopes.size(); i++)
        {
          int r = envelopes[i][1];
          if(r > ret.back())
          {
            ret.push_back(r);
          }
          else
          {
            int left = 0, right = ret.size() - 1;
            while(left < right)
            {
              int mid = (left + right) / 2;
              if(ret[mid] >= r) right = mid;
              else left = mid + 1;
            }
            ret[left] = r;
          }
        }

        return ret.size();
    }
};

可被三整除的最大和

image-20240326191035787

题目分析

image-20240326193532737

引入一个新问题,如何求出最小值和次小值

image-20240326193915292

代码

class Solution {
public:
    int maxSumDivThree(vector<int>& nums) {
       const int INF = 0x3f3f3f3f;
       int x1 = INF, x2 = INF, y1 = INF, y2 = INF;
       int sum = 0;
       for(auto x : nums)
       {
          sum += x;
          if(x % 3 == 1)
          {
            if(x < x1) 
            {
              x2 = x1;
              x1 = x;
            }
            else if(x < x2) x2 = x;
          }
          else if(x % 3 == 2)
          {
            if(x < y1)
            {
              y2 = y1;
              y1 = x;
            }
            else if(x < y2) y2 = x; 
          }
       }

       if(sum % 3 == 0) return sum;
       else if(sum % 3 == 1) return max(sum - x1, sum - y1 - y2);
       else return max(sum - y1, sum - x1 - x2);
    }
};

距离相等的条形码

image-20240326195602785

题目分析

把数字间隔1个数字放,先放次数最多的,放下的数字的顺序怎么放都可以。

证明

题目一定是有解的,那么出现最多的那个数字不能超过 n + 1 / 2次,因为如果有n个抽屉,放n + 1 个东西,必然有一个抽屉放2个,分情况讨论。

如果最多出现的数字次数刚好是 n + 1 / 2,那么剩下的随便放,都不相邻

如果出现的数字次数小于 n + 1 / 2,那更不可能相邻了,如果有相邻的说明这个数字出现的次数一定比 这个数字出现的次数多,那它就是最多出现次数的数字了,所以先放次数最多的,放下的数字的顺序怎么放都可以。

代码

class Solution {
public:
    vector<int> rearrangeBarcodes(vector<int>& barcodes) {
      unordered_map<int, int> hash;
      int n = barcodes.size();
      int max_val = 0, max_count = 0;
      for(auto x : barcodes)
      {
        if(max_count < ++hash[x])
        {
          max_val = x;
          max_count = hash[x];
        }
      }

      vector<int> ret(n);
      int index = 0;
      //先放出现次数最多的数字
      for(int i = 0; i < max_count; i++)
      {
        ret[index] = max_val;
        index += 2;
      }

      //处理剩下的数字
      hash.erase(max_val);
      for(auto& [x, y] : hash)
      {
        for(int i = 0; i < y; i++)
        {
          if(index >= n)index = 1;
           ret[index] = x;
            index += 2;
        }
      }
      return ret;
    }
};

重构字符串

image-20240326203040064

代码

这道题目和上一题的区别就是这道题目可能是没有解的。

class Solution {
public:
    string reorganizeString(string s) {
      int hash[26] = {0};
      int n = s.size();
      char max_ch = ' ';
      int max_count = 0;
      for(const auto ch : s)
      {
        if(max_count < ++hash[ch - 'a'])
        {
          max_count = hash[ch - 'a'];
          max_ch = ch;
        }
      }
      if(max_count > (n + 1) / 2 ) return "";
      string ret(n, ' ');
      int index = 0;
      //先放最多的英文
      for(int i = 0; i < max_count; i++)
      {
        ret[index] = max_ch;
        index += 2;
      }
      hash[max_ch - 'a'] = 0;
      //放剩下的英文
     for(int i = 0; i < 26; i++)
     {
        for(int j = 0; j < hash[i]; j++)
        {
          if(index >= n) index = 1;
          ret[index] = 'a' + i;
          index += 2;
        }
     }
      return ret;
    }
};

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

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

相关文章

Web举例:防火墙二层,上下行连接交换机的主备备份组网

Web举例&#xff1a;防火墙二层&#xff0c;上下行连接交换机的主备备份组网 介绍了业务接口工作在二层&#xff0c;上下行连接交换机的主备备份组网的Web举例。 组网需求 如图1所示&#xff0c;两台FW的业务接口都工作在二层&#xff0c;上下行分别连接交换机。FW的上下行业…

【爬虫基础】第2讲 使用Urllib库创建第一个爬虫程序

Urllib 是 Python 的标准库&#xff0c;它提供了一系列用于处理 URL 的函数和类&#xff0c;包括发送 HTTP 请求、处理 HTTP 响应、解析 URL 等功能。可以使用 urllib 来编写简单的网络爬虫。 request&#xff1a;它是最基本的HTTP请求模块&#xff0c;可以用来模拟发送请求。只…

2024年 (第十届)全国大学生统计建模大赛优秀论文解析——中国经济发展与碳排放库兹涅茨曲线的验证研究

一、摘要 二、引言 三、文献综述 四、研究方法 五、数据来源与分析 5.1变量选择 5.2数据来源 六、模型研究与建立过程 七、结果分析 八、结论及建议 参考文献: 更多资料请联系CSDN 建模忠哥小师妹

【WEEK4】 【DAY5】AJAX第二部分【中文版】

2024.3.22 Friday 接上文【WEEK4】 【DAY4】AJAX第一部分【中文版】 目录 8.4.Ajax异步加载数据8.4.1.新建User.java8.4.2.在pom.xml中添加lombok、jackson支持8.4.3.更改tomcat设置8.4.4.修改AjaxController.java8.4.5.新建test2.jsp8.4.5.1.注意&#xff1a;和WEB-INF平级&…

【SpringBoot整合系列】SpringBoot3.x整合Swagger

目录 产生背景官方解释&#xff1a;作用SpringBoot3整合Swagger注意事项swagger3 常用注解SpringBoot3.x整合Swagger1.创建工程(jdk:17,boot:3.2.4)2.引入pom依赖3.application.yml添加配置4.添加swagger3.0配置5.控制器层(Controller)6.模型层(Model)7.启动并测试【Get请求接口…

AlphaGPT在法律大模型圈子火了,案件仅需3分钟搞定

AI不断应用在新的领域&#xff0c;法律行业也不例外。法律AI大模型的到来无疑给业内法律人造成了一定的冲击&#xff0c;但也有更多专业人士指出&#xff0c;法律AI是未来的大趋势&#xff0c;我们要学会利用它&#xff0c;而不是逃避它。 AlphaGPT是法律AI大模型的代表性产品…

[伴学笔记]02-应用视角的操作系统 [南京大学2024操作系统]

文章目录 前言jyy: 02-应用视角的操作系统Everything(二进制程序) 状态机什么是状态机? 操作系统上的应用程序理解高级语言程序 信息来源: 前言 督促自己,同时分享所得,阅读完本篇大约需要10分钟,希望为朋友的技术精进之路尽到绵薄之力.码字不易,望能给个点赞和收藏,以激励笔…

docker安装redis 6.2.7 并 远程连接

阿里云ecs服务器&#xff0c;docker安装redis 6.2.7 并 远程连接 文章目录 阿里云ecs服务器&#xff0c;docker安装redis 6.2.7 并 远程连接1. 拉取redis镜像2. 查看是否下载成功3. 挂载配置文件4. 下载reids配置文件(redis.conf)5. docker创建redis容器6. 查看redis容器运行状…

css预处理器scss的使用如何全局引入

目录 scss 基本功能 1、嵌套 2、变量 $ 3、mixin 和 include 4、extend 5、import scss 在项目中的使用 1、存放 scss 文件 2、引入 variables 和 mixins 2-1、局部引入 2-2、全局引入 3、入口文件中引入其他文件 项目中使用 css 预处理器&#xff0c;可以提高 cs…

boot整合xfire

最近换了项目组&#xff0c;框架使用的boot整合的xfire&#xff0c;之前没使用过xfire&#xff0c;所以写个例子记录下&#xff0c;看 前辈的帖子 整理下 pom文件 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot…

上位机图像处理和嵌入式模块部署(qmacvisual图像识别)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 所谓图像识别&#xff0c;就是对图像进行分类处理&#xff0c;比如说判断图像上面的物体是飞机、还是蝴蝶。在深度学习和卷积神经网络CNN不像现在这…

企微获客助手功能,行为触发如何实现回传的?

获客助手&#xff0c;这个听起来就相当酷炫的名字&#xff0c;它实际上是一个帮助企业将推广流量快速导入企业微信的神器。通过它&#xff0c;企业可以吸引越来越多的用户加为好友&#xff0c;从而建立起更紧密的客户关系。但是&#xff0c;如何进一步提升导入企业微信的流量质…

IntersectionObserver:实现滚动动画、懒加载、虚拟列表

认识 浏览器自带的适用于 「监听元素与视窗交叉状态」 的观察器&#xff1a;「IntersectionObserver&#xff08;交叉观察器&#xff09;」 IntersectionObserver 是一种 JavaScript API&#xff0c;它提供了一种异步监测元素与其祖先容器或视口之间交叉状态的方法。简单来说&…

数据库备份工具(实现数据定时覆盖)

数据库备份工具&#xff08;实现数据定时覆盖&#xff09; 永远热爱&#xff0c;永远执着&#xff01; 工具介绍 自动化测试数据库更新调度程序 这段 Python 脚本自动化了每天定时从生产数据库更新测试数据库的过程。它利用了 schedule 库来安排并执行每天指定时间的更新任务…

(vue)el-table表格回显返回的已勾选的数据

(vue)el-table表格编辑时回显返回的已勾选的数据 tableData数据&#xff1a; el-tableref"multipleTable":data"tableData"... >...<el-table-column prop"result" label"相关.." align"center" width"220"…

【Java程序设计】【C00344】基于Springboot的船舶维保管理系统(有论文)

基于Springboot的船舶维保管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及i…

NX二次开发判断两对象是否相连(相交,相离)

一、概述 最近学习如何判断两根曲线是否连接&#xff08;不是相交&#xff0c;两条直线有一个端点重合&#xff09;&#xff0c;网上说到两种方法&#xff0c;一种是第一种方法&#xff0c;UF_MODL_ask_minimum_dist_3函数判断两个对象的距离&#xff0c;测得的距离等于零&…

【python】进程和线程

文章目录 进程创建进程os.fork() - 只适用于linux/unix/macmultiprocessing模块Process 类Pool进程池进程间通信队列queue常见用法管道pipes线程创建线程线程间通信互斥锁队列进程 任务管理器中一个任务就是一个进程 创建进程 os.fork() - 只适用于linux/unix/mac multipr…

Halcon与C#联合开发——1.读取图片、图像二值化

在vs中引入halcon控件 修改目标平台为 x64 拖出三个控件 代码展示 using System; using System.Windows.Forms; //引用支持halcon的命名空间 using HalconDotNet;namespace _1.HalconDisplay {public partial class Form1 : Form {// HObject 是Halcon库中表示图像和其他图形…

CentOS7下nginx部署测试

nginx部署测试 #安装程序和依赖yum install -y vim net-tools wgetyum -y install gcc pcre-devel zlib-devel openssl openssl-devel #下载nginx mkdir /opt/nginx cd /opt/nginx wget https://nginx.org/download/nginx-1.20.2.tar.gz#解压 tar zxvf nginx-1.20.2.tar.gz c…