算法篇-------贪心2

news2025/3/1 3:57:03

文章目录

    • 题目1-------活动选择
    • 题目2-----无重叠区间
    • 题目3------最多可以参加的会议数目
    • 题目4-------去除重复字母
    • 题目5------移掉K位数字
    • 题目6-----拼接最大数

题目1-------活动选择

有n个需要在同一天使用同一个教室的活动a1, a2, …, an,教室同一时刻只能由一个活动使用。每个活动a[i]都有一个
开始时间s[i]和结束时间f[i]。一旦被选择后,活动a[i]就占据半开时间区间[s[i],f[i])。如果[s[i],f[i])和[s[j],f[j])互不重
叠,a[i]和a[j]两个活动就可以被安排在这一天。求使得尽量多的活动能不冲突的举行的最大数量

怎么考虑呢?
我们优先考虑结束时间最早的活动,结束时间最早意味着能安排更多的活动。
贪心-------通过一系列的局部最优达到总体最优,(只考虑眼前)

选择最早开始和最短时间都不能达到目的。例如下面的3个活动:
在这里插入图片描述

代码分享:

class Sort
{
public:
	bool operator()(vector<int> a, vector<int> b)
	{
		return a[1] < b[1];
	}
};

//vv是已经按照最短结束时间排序好的
int get_max_act(const vector<vector<int>>& vv)
{
	int cnt = 1;
	int endtime = vv[0][1];
	for (int i = 1; i < vv.size(); i++)
	{
		//可以安排下一个活动了
		//下一个活动的起始时间大于当前活动的结束时间
		if (vv[i][0] >= endtime) 
		{
			endtime = vv[i][1];
			cnt++;
		}
	}

	return cnt;
}

题目2-----无重叠区间

力扣题:435

这一题和上面一题的思路一样, 优先选择结束区间最小的,使之能有更多的区间,然后达到删除最小区间的目的。
也就是说,通过一系列的局部最优达到整体最优。

class Solution {
public:
    class Sort
    {
    public:
           bool operator()(const vector<int>& a, const vector<int>& b)
           {
               return a[1] < b[1];
           }
    };

    int eraseOverlapIntervals(vector<vector<int>>& intervals) 
    {
        if(intervals.empty())
            return 0;

        sort(intervals.begin(), intervals.end(), Sort());
        int end = intervals[0][1];
        int num = 1;
        for(int i = 1; i < intervals.size(); i++)
        {
            if(intervals[i][0] >= end)
            {
                end = intervals[i][1];
                num++;
            }
        }

        return intervals.size()- num;

    }
};

题目3------最多可以参加的会议数目

力扣:1353

这个题和上面几个题有些不同,上面的是时间间隔, 而这一题用的是其中某一天
也就是说,在1-----10 0001天我们都是可以去开会议的。
怎么去选择会议呢? 优先选择开始时间最早,结束时间最短的。

这个题的核心思路是:
优先选择开始时间最早, 但是呢很多会议也会存在开始时间一样的情况,所以呢我们再次进行选择,选择结束时间最早的。
在这里插入图片描述

这一题稍微有一些复杂,所以提供了不少的注释
代码:

class Solution {
public:
    int maxEvents(vector<vector<int>>& events) 
    {
        //因为开始时间的范围是在1--10^5
        vector<vector<int>> vv(100001);
        
        //按照起始实际按分类,将第i个会议分到同一个一维数组
        for(int i = 0; i < events.size(); i++)
            vv[events[i][0]].push_back(i);
        
        //优先队列类型是int, 容器是适配器用vector, 采用小堆
        int ans = 0;
        priority_queue<int, vector<int>, greater<int>> pq;

        //遍历所有可以执行的时间,看看某一个会议能不能在这一天去执行
        for(int i = 0; i < 100001; i++)
        {
            for(auto e : vv[i])  //e是开始时间为vv[i]的第几个会议
              pq.push(events[e][1]);   //将其结束时间入队列
            
            //i表示当前执行的时间,而队列存放的是结束时间
            //只要比i小的结束时间表明该会议已经错过了
            while(!pq.empty() && pq.top() < i)
               pq.pop();
            
            //从里面找出一个会议结束时间最早的出来开。
            if(!pq.empty())
            {
                ans++;
                pq.pop();
            }
        }
        
        return ans;
    }
};

题目4-------去除重复字母

力扣题:316

在这里插入图片描述

class Solution {
public:
    string removeDuplicateLetters(string s) 
    {
        unordered_map<char, int> cnt;
        unordered_map<char, bool> inst;
        stack<char> st;

        for(auto e : s)       //用map统计次数
              cnt[e]++;

        for(int i = 0; i < s.size(); i++)
        {
            char c = s[i];
            if(inst[c])  //要操作的元素已经在栈里面,默认已经放好了
            {
                cnt[c]--;
                continue;
            }
           
            //如果当前操作的元素小于栈顶元素,并且栈顶元素还存在
            while(!st.empty() && c < st.top() && cnt[st.top()] > 0)
            {
                inst[st.top()] = false; //出栈了,栈顶元素肯定就不在栈了
                st.pop();
            }
            
            inst[c] = true; //入栈后就改状态
            st.push(c);
            cnt[c]--;
        }
        
        string ans;
        while(!st.empty())
        {
            ans += st.top();
            st.pop();
        }
        
        reverse(ans.begin(), ans.end()); //需要逆序操作的
        return ans;
    }
};

题目5------移掉K位数字

力扣题:402
在这里插入图片描述

class Solution {
public:
    string removeKdigits(string num, int k)
    {
         string ans;
         stack<char> st;

         for(int i = 0; i < num.size(); i++)
         {
             char c = num[i];
             
             //当前操作的元素 < 栈顶元素 &&  有删除的机会 k > 0 
             while(!st.empty() && c < st.top() && k > 0)
             {
                 st.pop();
                 k--;
             }
            
            //栈位空, 当前为0,直接不考虑
            if(st.empty() && c == '0')
                   continue;

             st.push(c);
         }
           
         while(!st.empty() && k--)   //如果还有删除的机会,直接删除
             st.pop();

        while(!st.empty())
        {
            ans += st.top();
            st.pop();
        }
        reverse(ans.begin(), ans.end());
        
        if(ans.empty())
              ans += "0";

        return ans;     
    }
};

题目6-----拼接最大数

力扣321

这一个题目代码虽然有一些长,但是逻辑比较简单,并不复杂。
在这里插入图片描述

class Solution {
public:

    //k是需要移除的个数
    vector<int> subNumber(const vector<int>& v, int k)
    {
        vector<int> ans;
        stack<int> st;
        for (int i = 0; i < v.size(); i++)
        {
            int c = v[i];

            while (!st.empty() && c > st.top() && k > 0)
            {
                st.pop();
                k--;
            }

            st.push(c);
        }

        while (!st.empty() && k > 0)
        {
            st.pop();
            k--;
        }

        while (!st.empty())
        {
            ans.push_back(st.top());
            st.pop();
        }

        reverse(ans.begin(), ans.end());
        return ans;
    }

    // v1 >= v2 返回true
    bool cmpArray(const vector<int>& v1, int i, const vector<int>& v2, int j)
    {
        while (i < v1.size() && j < v2.size())
        {
            if (v1[i] > v2[j])
                return true;

            if (v1[i] < v2[j])
                return false;

            i++;
            j++;
        }

        //走到这里, 无非就是一个为空, 一个不为空
        if (j == v2.size())
            return true;

        return false;
    }

    vector<int> mergeArray(const vector<int>& v1, const vector<int>& v2)
    {
        int i = 0, j = 0;
        vector<int> ans;

        while (i < v1.size() && j < v2.size())
        {
            if (cmpArray(v1, i, v2, j))
            {
                ans.push_back(v1[i]);
                i++;
            }
            else
            {
                ans.push_back(v2[j]);
                j++;
            }
        }

        while (i < v1.size())
        {
            ans.push_back(v1[i++]);
        }

        while (j < v2.size())
        {
            ans.push_back(v2[j++]);
        }

        return ans;
    }

    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k)
    {
        //下面一个数组拿出多少个元素,另一个数组拿出一个元素边界不好控制
        //我们用举例来: m = 4 , n = 6,显然对于nums2来说
        //最少拿出一个元素, 最多拿出5个元素
        int m = nums1.size(), n = nums2.size();
        int begin = max(0, k - m), end = min(k, n);

        vector<int> ans;
        for (int i = begin; i <= end; i++)
        {
            //对于nums2来说,拿出i个元素, 去掉n - i 个元素
            //对于nums1来说,就要拿出k - i个, 去掉m - k + i个元素
            vector<int> subnum1 = subNumber(nums2, n - i);
            vector<int> subnum2 = subNumber(nums1, m - k + i);

            vector<int> ret = mergeArray(subnum1, subnum2);
            if (cmpArray(ret, 0, ans, 0))
                swap(ret, ans);  //c++11支持右值引用,可以窃取资源
        }

        return ans;
    }
};

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

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

相关文章

MapReduce基础

MapReduce入门 理解MapReduce的思想 MapReduce的思想核心是先分再合&#xff0c;分而治之所谓的分而治之&#xff0c;就是把一个复杂的问题&#xff0c;按照一定的分解方法分为等价的规模的若干部分&#xff0c;然后捉个解决&#xff0c;分别找出各个部分的结果没然后将各个部…

【学习笔记】mac安装maven与idea自带maven

一、安装Maven 1.1 场景一&#xff1a;mac安装Maven step1: 下载maven 到 maven官网下载压缩包&#xff0c;这里下载 apache-maven-3.8.6-bin.zip 压缩包&#xff1a; step2: 解压安装 解压maven压缩包&#xff0c;将解压得到的maven文件夹 “apache-maven-3.8.6” 放到合适…

Ubuntu22.04系统安装Unreal Engine 5.1.0

1.实现目标 在Ubuntu22.04系统上从源码构建安装Unreal Engine 5.1.0。 2.实现过程 2.1 正常流程 (1)从github上下载最新的release版本的源代码:5.1.0 release。 (2)解压缩代码,并打开终端,执行 ./Setup.sh,下载所需的各项依赖,文件大小约20GB,需下载2-3小时。 (…

【每日一题Day33】LC799香槟塔 | 动态规划

香槟塔【LC799】 我们把玻璃杯摆成金字塔的形状&#xff0c;其中 第一层 有 1 个玻璃杯&#xff0c; 第二层 有 2 个&#xff0c;依次类推到第 100 层&#xff0c;每个玻璃杯 (250ml) 将盛有香槟。 从顶层的第一个玻璃杯开始倾倒一些香槟&#xff0c;当顶层的杯子满了&#xff…

springmvc-day01

springmvc-day01 第一节 SpringMVC概述 1. SpringMVC 优势 SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后&#xff0c;目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首…

pytest集成allure报告(allure安装及配置以及如何实现集成)

一、allure安装及环境变量配置 1、先保证本地已装jdk1.8 首先安装JDK1.8&#xff0c;添加到环境变量path。 具体可以查看文章&#xff1a;https://blog.csdn.net/weixin_40608713/article/details/116103153?ops_request_misc%257B%2522request%255Fid%2522%253A%2522166892…

07_通信过程

知识点1【给路由器添加一块网卡】 知识点2【演示浏览器访问web服务器】 知识点2【局域网的划分】&#xff08;补充&#xff09; 知识点3【跨外网的不同局域网通信过程】&#xff08;补充&#xff09; 知识点4【LInux下的防火墙】&#xff08;了解&#xff09; 防火墙的分类…

【虚幻引擎UE】UE4/UE5 GIS相关插件推荐及使用介绍

一、Cesium for Unreal&#xff08;Cesium插件&#xff09; 二、SuperMap Scene SDKs_Unreal Engine&#xff08;超图地图插件&#xff09; 提供了从SuperMap平台或其他开放在线地图访问真实世界地理空间3D数据的功能。 三、Vitruvio CityEngine Plugin&#xff08;CityEngine…

Python图像处理笔记

文章目录一. Pillow处理图片1.1 Pillow安装1.2 Pillow基本使用二. Matplotlib包中的图像模块2.1 简介2.2 API简介三. ndarray图像操作练习3.1 旋转图片3.2 图片打码3.3 图片拼接3.4 图片切割四. 图像灰度化4.1 简介4.2 灰度化方法五. OpenCV使用入门5.1 简介5.2 OpenCV基本使用…

Android TextView富文本SpannableStringBuilder的使用详解

背景&#xff1a; 在android开发过程中&#xff0c;做内容的时候&#xff0c;不仅只有字符&#xff0c;基本都是图文混排&#xff0c;甚至还会对内容中某段文字进行特殊处理&#xff0c;比如&#xff1a;字体加粗、字体变大、改变字体颜色、对某一段文字新增点击事件&#xff…

Redis缓存——快速入门

目录 1、Redis概述 1.1、NoSQL 1.2、缓存的需求 2、Redis简介及安装 2.2、redis的特点 2.3、redis下载 2.4、window安装 2.5、linux安装 3、Redis操作 3.1、多数据库 3.2、选择数据库 3.3、清空数据库 3.4、基本命令 4、五种数据类型 4.1、字符串&#xff08;st…

论文笔记:Ontology-enhanced Prompt-tuning for Few-shot Learning

论文来源&#xff1a;WWW 2022 论文地址&#xff1a;https://arxiv.org/pdf/2201.11332.pdfhttps://arxiv.org/pdf/2201.11332.pdf 论文代码&#xff1a;暂未公开 笔记仅供参考&#xff0c;撰写不易&#xff0c;请勿恶意转载抄袭&#xff01; Abstract 小样本学习旨在基于…

【数据结构】队列

1.啥是队列 2.队列实现 3.Queue接口的介绍以及队列的使用 4.相关队列的例子 &#xff08;1&#xff09;啥是队列 我们之前讲解了栈&#xff0c;栈和队列是有点区别的 我们说过栈是一种先进后出的数据结构&#xff0c;你可以把它想象成羽毛球筒&#xff1b;然而队列属于一种先…

一文读懂VMware虚拟化技术(含超融合)

1. 概述 1.1 为什么使用虚拟化 基于云服务器业务&#xff0c;很多公司不需要那么强大的服务器&#xff0c;将服务器虚拟化之后分开卖收益更高 比如租房&#xff0c;有一个100平面的房子&#xff0c;整租可以一个月房租8000&#xff0c;划分4个区域分这组&#xff0c;可以每个…

OAuth2.0

OAthu2.0参考链接1 OIDC&#xff08;OpenId Connect&#xff09;身份认证参考链接 一、定义 OAuth2.0是OAuth协议的延续版本&#xff0c;但不向前兼容OAuth 1.0(即完全废止了OAuth1.0)。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批…

《大数据分析-数据仓库项目实战》--阅读笔记

本文是《大数据分析-数据仓库项目实战》阅读笔记。 内容全部摘抄于本书。 算入门教材、文中有大量软件的安装步骤、对技术细节未过多涉及。 前言描述 大数据时代&#xff0c;需要考虑数据的采集、存储、计算处理等方式。 数据仓库建模方式&#xff1a;确定业务过程、声明粒度…

统计信号处理基础 习题解答6-10

题目&#xff1a; 我们继续习题6.9&#xff0c;考察在有色噪声环境下OOK系统信号选择的问题&#xff0c;令噪声 为零均值的WSS随机过程&#xff0c;ACF为 求PSD&#xff0c;并且对于 画出PSD的图形。和前一个系统一样&#xff0c;对于N50,求产生BLUE最小方差频率。提示&#x…

Espressif-IDE NameError: name ‘websocket‘ is not defined 解决方法

前言 ESP32 具有wifi 与 蓝牙&#xff0c;性价比比较高&#xff0c;一些嵌入式开发中经常用到&#xff0c;最近更新了一下 ESP32的开发环境&#xff0c; ESP32 开发工具下载地址&#xff1a;https://dl.espressif.cn/dl/esp-idf/ 下载文件&#xff1a;espressif-ide-setup-2.7…

HIve数仓新零售项目DWS层的构建(Grouping sets)模型

HIve数仓新零售项目 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kaf…

一文搞懂《前后端动态路由权限》

前言 本文主要针对后台管理系统的权限问题&#xff0c;即不同权限对应着不同的路由&#xff0c;同时侧边栏的路由也需要根据权限的不同异步生成。我们知道&#xff0c;权限那肯定是对应用户的&#xff0c;那么就会涉及到用户登录模块&#xff0c;所以这里也简单说一下实现登录的…