【C++刷题】优选算法——贪心第一辑

news2024/11/24 12:33:43
  • 什么是贪心算法
    贪心策略:局部最优 -> 全局最优
    “贪婪+鼠目寸光”
    1、把解决问题的过程分为若干步
    2、解决每一步的时候,都选择当前看起来“最优的”解法
    3、“希望”得到全局最优解

  • 贪心算法的特点
    贪心策略的提出是没有标准或者模板的
    正确的贪心策略的提出是要有数学依据的

  1. 柠檬水找零
    在这里插入图片描述
class Solution {
    unordered_map<int, int> change = {
        {5, 0},
        {10, 0},
        {20, 0},
    };
public:
    bool lemonadeChange(vector<int>& bills) {
        for (int e : bills) {
            if (e == 5) {
                change[5]++;
            } else if (e == 10) {
                if (change[5] >= 1) {
                    change[5]--;
                    change[10]++;
                } else {
                    return false;
                }
            } else {
                if (change[10] >= 1 && change[5] >= 1) {
                    change[5]--;
                    change[10]--;
                    change[20]++;
                }
                else if (change[5] >= 3) {
                    change[5] -= 3;
                    change[20]++;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
};
  1. 将数组和减半的最少操作次数
    在这里插入图片描述
class Solution {
    double sum = 0;
    double mid = 0;
    int count = 0;
    priority_queue<double> pq;
public:
    int halveArray(vector<int>& nums) {
        for (int e : nums) {
            sum += e;
            pq.push(e);
        }

        mid = sum / 2;
        sum = 0;
        while (sum < mid) {
            double top = pq.top(); pq.pop();
            top /= 2;
            sum += top;
            ++count;
            pq.push(top);
        }
        return count;
    }
};
  1. 最大数
    在这里插入图片描述
class Solution {
    string ret;
    vector<string> v;
public:
    string largestNumber(vector<int>& nums) {        
        for (int e : nums) {
            v.push_back(to_string(e));
        }
        ranges::sort(v, [](const string& left, const string& right){
            return left + right > right + left;
        });
        if (v.front() == "0") return "0";

        for (const string& s : v) {
            ret += s;
        }
        
        return ret;
    }
};
  1. 摆动序列
    在这里插入图片描述
// 解法一
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {

        int left = nums[0];
        int count = 1;
        int right;
        bool flag;

        int i = 1;
        for (; i < nums.size();) {
            if (nums[i] > left) {
                right = nums[i];
                ++i;
                while (i < nums.size() && nums[i] >= right) {
                    right = nums[i];
                    ++i;
                }
                ++count;
                flag = true; // true 为上升
                left = right;
                break;
            } else if (nums[i] < left) {
                right = nums[i];
                ++i;
                while (i < nums.size() && nums[i] <= right) {
                    right = nums[i];
                    ++i;
                }
                ++count;
                flag = false; // false 为下降
                left = right;
                break;
            } else {
                ++i;
            }
        }

        for (; i < nums.size();) {
            if (flag) { // 前一个是上升
                if (nums[i] < left) {
                    right = nums[i];
                    ++i;
                    while (i < nums.size() && nums[i] <= right) {
                        right = nums[i];
                        ++i;
                    }
                    ++count;
                    flag = !flag;
                    left = right;
                } else {
                    ++i;
                }
            } else {
                if (nums[i] > left) {
                    right = nums[i];
                    ++i;
                    while (i < nums.size() && nums[i] >= right) {
                        right = nums[i];
                        ++i;
                    }
                    ++count;
                    flag = !flag;
                    left = right;
                } else {
                    ++i;
                }
            }
        }
        return count;
    }
};

// 解法二
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() < 2) return 1;

        int ret = 0, left = 0;
        for (int i = 1; i < nums.size(); ++i) {
            int right = nums[i] - nums[i-1];
            if (right == 0) continue;
            if (left * right <= 0) ++ret;
            left = right;
        }
        return ret + 1;
    }
};
  1. 最长递增子序列
    在这里插入图片描述
    存什么:所有长度为 n 的递增子序列中,最后一个元素的最小值
    存哪里:所有大于等于 nums[i] 的最小值的位置
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> v = { nums[0] };
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] < v.back()) {
                int left = 0, right = v.size() - 1;
                while (left < right) {
                    int mid = left + (right - left) / 2;
                    if (v[mid] < nums[i]) {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                v[left] = nums[i];
            } else if (nums[i] > v.back()) {
                v.push_back(nums[i]);
            }
        }
        return v.size();
    }
};
  1. 递增的三元子序列
    在这里插入图片描述
bool increasingTriplet(vector<int>& nums) {
    vector<int> tuple = { nums[0] };
    for (int i = 1; i < nums.size(); ++i) {
        if (nums[i] > tuple.back()) {
            tuple.push_back(nums[i]);
            if (tuple.size() == 3) return true;
        } else {
            for (int j = 0; j < tuple.size(); ++j) {
                if (nums[i] <= tuple[j]) {
                    tuple[j] = nums[i];
                    break;
                }
            }
        }
    }
    return false;
}

// 简化
bool increasingTriplet(vector<int>& nums) {
    int num1 = nums[0], num2 = INT_MAX;
    for (int i = 0; i < nums.size(); ++i) {
        if (nums[i] > num2) return true;
        else if (nums[i] <= num1) num1 = nums[i];
        else num2 = nums[i];
    }
    return false;
}
  1. 最长连续递增序列
    在这里插入图片描述
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        int ret = 0;
        int left = 0, right = 1;
        while (right < nums.size()) {
            int cur_len = 0;
            while (right < nums.size() && nums[left++] < nums[right++]) {
                ++cur_len;
            }
            ret = max(ret, cur_len);
        }
        return ret + 1;
    }
};
  1. 买卖股票的最佳时机
    在这里插入图片描述
int maxProfit(vector<int>& prices) {
    int ret = 0;
    int prev_min = prices[0];
    for (int i = 1; i < prices.size(); ++i) {
        ret = max(ret, prices[i] - prev_min);
        prev_min = min(prev_min, prices[i]);
    }
    return ret;
}
  1. 买卖股票的最佳时机 II
    在这里插入图片描述
int maxProfit(vector<int>& prices) {
    int ret = 0;
    for (int i = 1; i < prices.size(); ++i) {
        if (prices[i] > prices[i-1]) ret += (prices[i] - prices[i-1]);
    }
    return ret;
}
  1. K 次取反后最大化的数组和
    在这里插入图片描述
class Solution {
    int ret = 0;
    int plus_min = INT_MAX;
    vector<int> minus;
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        for (int e : nums) {
            if (e < 0) minus.push_back(e);
            else {
                ret += e;
                plus_min = min(plus_min, e);
            }
        }

        if (k > minus.size()) {
            for (int e : minus) {
                ret += -e;
                plus_min = min(plus_min, -e);
            }
            k -= minus.size();
            if (k % 2) ret -= 2 * plus_min;
        } else {
            ranges::sort(minus);
            for (int i = 0; i < k; ++i) ret += -minus[i];
            for (int i = k; i < minus.size(); ++i) ret += minus[i];
        }
        return ret;
    }
};

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

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

相关文章

项目小结(中)

一.文件分片上传 在文件上传的逻辑中&#xff0c;文件以MD5唯一&#xff0c;然后记录已经储存的文件md5&#xff0c;如果已上传&#xff0c;就秒传&#xff0c;并记录班级上传文件信息。 如果请求文件上传时&#xff0c;发现班级已经上传了一部分&#xff0c;这里就会把班级上…

秋招复习笔记——八股文部分:网络IP

终于来到了网络的最后一篇&#xff0c;继续加油&#xff01; IP 知识全家桶 IP 基本认识 IP 在 TCP/IP 参考模型中处于第三层&#xff0c;也就是网络层。 网络层的主要作用是&#xff1a;实现主机与主机之间的通信&#xff0c;也叫点对点&#xff08;end to end&#xff09…

【Vue3】Pinia修改数据

【Vue3】Pinia修改数据 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子…

锐捷RCNA | 远程登录与路由技术

锐捷RCNA | 远程登录与路由技术 一、远程登录配置1. Telnet远程登录介绍2. 案例1--设置远程登录密码实现远程登录3. 案例2--定义不同用户账户实现远程用户权限隔离4. SSH远程登录介绍5. 案例--通过SSH功能远程管理设备 二、路由技术1. 直连路由的数据通信2. 间接路由的数据通信…

标准IO

fprintf和fscanf fprintf int printf(const char *format, ...); 把数据输出到终端 int fprintf(FILE *stream, const char *format, ...); 功能&#xff1a; 将format字符串中的内容&#xff0c;输出到stream文件流指针指向的文件中去&#xff0c;想要将数据以何种形式输…

基于XxlCrawler的Java执行JS渲染方式实战-以获取商飞C919飞行照片为例

目录 前言 一、抓取目标解析 1、原始网站介绍 2、列表页面结构解析 二、XxlCrawler的常规配置 1、PageVo对象的定义 2、定义XxlCrawler并启动 三、使用HtmlUnit来执行动态渲染 1、在pom.xml中加入htmlunit的引用 2、设置PageLoader加载器 3、执行抓取 四、总结 前言…

看,esp8266就是这么简单

材料准备 1.esp 8266 2.一条可以传输数据的数据线 3一台电脑 前言 如今是物联网的时代&#xff0c;例如“智能家居&#xff0c;无人驾驶……”&#xff0c;多方面的进行物联网改革与创新。那其中&#xff0c;物联网主要的是联网。那通常都是以“esp 8266”和“esp 32”占据了…

在Kylin服务器安装PostgreSQL16数据库

1、下载PostgreSQL16安装包 下载地址https://www.postgresql.org/ftp/source/v16.3/ 2、安装依赖和ICU库 查看服务器版本 yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel python-devel gcc-c opens…

在抖音做电商推广,货架场非做不可

前一段时间跟几个做电商的朋友聊天&#xff0c;我发现大家的干劲儿还挺满的&#xff0c;讨论的话题也出奇地一致&#xff1a;要找新增量。 其中有个朋友是做服装品类的&#xff0c;做得还不错。我请教他秘诀&#xff0c;他说&#xff1a;做电商&#xff0c;推广拿量非常关键。…

MySQL笔记(七):索引

一、索引优化速度 创建对应字段的索引&#xff0c;只对该列有效&#xff0c;只能提高该列的查询速度 创建索引后&#xff0c;查询速度变快&#xff0c;但是表占用空间变大 create index 索引名 on 表名(需要创建索引的列)二、索引的原理 普通索引允许该字段重复 全文索引&#…

Resize Observer监测DOM元素尺寸改变的神器

前言 大家在遇到需要监测DOM元素尺寸大小的需求时&#xff0c;可能第一时间想到的都是使用window.addEventListener来监听resize 事件&#xff0c; 但是reize事件会在一秒内触发将近60次&#xff0c;所以很容易在改变窗口大小时导致性能问题。因为它会监听我们页面每个元素的…

MySQL总体功能

基于Innodb存储引擎的讨论 MySQL 核心功能 功能解决的问题ACID模型数据并发访问&#xff0c;和奔溃恢复安全问题,一致性&奔溃恢复索引数据查询效率问题备份容错设计,解决硬件错误带来的问题复制数据迁移监控执行数据库操作的异常记录

《嵌入式 - 嵌入式大杂烩》ARM Cortex-M寄存器详解

1 ARM Cortex-M寄存器概述 ARM Cortex-M提供了 16 个 32 位的通用寄存器(R0 - R15),如下图所示。前15个(R0 - R14)可以用作通用的数据存储,R15 是程序计数器 PC,用来保存将要执行的指令。除了通用寄存器,还有一些特殊功能寄存器。特殊功能寄存器有预定义的功能,而且必须通…

Java编码算法

编码 1.编码算法2.URL编码**URLEncoder类&#xff0c;主要进行编码****URLDecoder类&#xff0c;主要进行解码** 3.Base64编码Base64编码Base64的补充字符Base64的占位符Base64的应用 结论&#xff1a; 1.编码算法 什么是编码? ASCII码就是一种编码&#xff0c;字母A的编码是…

C语言典型例题28

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.5 输入一个华氏温度&#xff0c;要求输出摄氏温度。公式为C5/9(F-32)&#xff0c;要求输出要有文字说明&#xff0c;取两位小数 数学知识&#xff1a; &#xff08;1&#xff09;华氏温度与摄氏温度&#x…

MySQL(六):mysql 约束

基本介绍&#xff1a;约束用于确保数据库的数据满足特定的商业规则&#xff0c;约束包括&#xff1a;not null、unique、primary key、foreign key 、check五种。 一、主键的使用&#xff08;primary key) 字段名 字段类型 primary key用于唯一的表示表行的数据&#xff0c;当…

SpringBoot基础 第二天

SpringBoot对静态资源的映射: (1) 要在src/main/resources文件夹下创建static和templates两个文件夹staitc存储静态资源,templates存储模板引擎 (2)要在pom.xml依赖下导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>…

VS项目打包成lib库并使用

一、新建一个静态库项目 一般要把项目设为Release模式 二、添加文件 将所需要打包的头文件、源文件添加到该静态库项目中 三、生成项目 生成成功后即可在Release文件夹出现找到相应的.lib文件 四、使用静态库 将静态库文件复制到项目文件夹中&#xff0c;然后在项目属性设…

LSV实验——部署DR模式集群

目录 一、实验环境 二、配置 1、LVS 2、router 3、client 4、RS 三、配置策略 1.Director服务器采用双IP桥接网络&#xff0c;一个是VPP&#xff0c;一个DIP 2.Web服务器采用和DIP相同的网段和Director连接 3.每个Web服务器配置VIP 4.每个web服务器可以出外网 一、实验环…

CENTOS9+RSYSLOG+LOGROTATE收集日志

系统版版本为CentOS Stream release 9 rsyslog和lograte通常系统已经安装了。 #rpm -qa | grep rsyslog rsyslog-logrotate-8.2310.0-4.el9.x86_64 rsyslog-8.2310.0-4.el9.x86_64 rsyslog-gnutls-8.2310.0-4.el9.x86_64 rsyslog-gssapi-8.2310.0-4.el9.x86_64 rsyslog-relp-…