贪心算法基础及leetcode例题
理论
本质:找到每个阶段的局部最优,然后去推导得到全局最优
两个极端:常识&&很难:
很多同学通过了贪心的题目,但都不知道自己用了贪心算法,因为贪心有时候就是常识性的推导,所以会认为本应该就这么做!
套路:
贪心没有套路,说白了就是常识性推导加上举反例
做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。
贪心算法一般分为如下四步:
将问题分解为若干个子问题
找出适合的贪心策略
求解每一个子问题的最优解
将局部最优解堆叠成全局最优解
这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。
Leetcode题目
简单题
455.分发饼干
思路:大饼干 喂 胃口大的kid,才能充分利用

class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int j=s.length-1;
int sum = 0;
for(int i=g.length-1;i>=0;i--){
if(j>=0 && s[j]>=g[i]){
sum++;
j--;
}
}
return sum;
}
}
中等题
序列问题---376. 摆动序列
思路:考虑情况

记录摆动条件:
prediff>0 && curdiff<0
或者 prediff<0 && curdiff>0
情况1:上下坡中有平坡

在图中,当i指向第一个2的时候,prediff > 0 && curdiff = 0 ,当 i 指向最后一个2的时候 prediff = 0 && curdiff < 0。
如果我们采用,删左面三个2的规则,那么 当 prediff = 0 && curdiff < 0 也要记录一个峰值。
综合到上述:记录条件【prediff>=0 && curdiff<0 或 prediff=<0 && curdiff>0】
情况2:首尾两端

result初始为1(默认最右面有一个峰值),
curDiff > 0 && preDiff <= 0,那么result++(计算了左面的峰值),最后得到的result就是2(峰值个数为2即摆动序列长度为2)
做法:初始化prediff=0
情况3:单调有平坡

只需要在 这个坡度 摆动变化的时候,更新prediff就行,这样prediff在 单调区间有平坡的时候 就不会发生变化
做法:调整prediff更新位置
java实现
class Solution {
public int wiggleMaxLength(int[] nums) {
int prediff = 0;//考虑只有两个元素的时候,默认为0;为头元素制造一个平坡
int curdiff = 0;
int result = 1;//默认最右端有坡度
//一个元素的时候
if(nums.length == 0) return result;
for(int i=0;i<nums.length-1;i++){//nums.length-1 因为最右端已经记录了
curdiff = nums[i+1] - nums[i];
if((prediff>=0 && curdiff <0) || (prediff<=0 && curdiff >0)){
result++;
prediff = curdiff;
}
//prediff = curdiff;
}
return result;
}
}
股票问题---122. 买卖股票的最佳时机 II
只有一只股票!当前只有买股票或者卖股票的操作
关键点:想到其实最终利润是可以分解的:每天的利润
贪心:只收集每次的正利润

其实我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间。
java
class Solution {
public int maxProfit(int[] prices) {
int sum = 0;
for(int i=0;i < prices.length-1;i++){
if((prices[i+1] - prices[i])>= 0){
sum += prices[i+1] - prices[i];
}
}
return sum;
}
}
两个维度权衡问题---135. 分发糖果
关键点:两边分别考虑
先确定 右边比左边高的情况;然后再确定 左边比右边高的情况
class Solution {
public int candy(int[] ratings) {
int sum = 0;
int len = ratings.length;
int[] candy = new int[len];
candy[0]=1;
for(int i=1;i<len;i++){
if(ratings[i] > ratings[i-1]){
candy[i] = candy[i-1] +1;
}else{
candy[i] =1;
}
}
for(int i=len-2;i>=0;i--){
if(ratings[i] > ratings[i+1]){
candy[i] = Math.max(candy[i+1] +1,candy[i]);
}
}
for(int i=0;i<len;i++){
sum += candy[i];
}
return sum;
}
}
贪心算法基础及leetcode例题的更多相关文章
- LEETCODE —— Best Time to Buy and Sell Stock II [贪心算法]
Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...
- Algorithm - 贪心算法使用场景 ( LEETCODE —— Best Time to Buy and Sell Stock II)
先看一道leetcode题: Best Time to Buy and Sell Stock II Say you have an array for which the ith element is ...
- C#LeetCode刷题-贪心算法
贪心算法篇 # 题名 刷题 通过率 难度 44 通配符匹配 17.8% 困难 45 跳跃游戏 II 25.5% 困难 55 跳跃游戏 30.6% 中等 122 买卖股票的最佳时机 II C ...
- LeetCode解题记录(贪心算法)(二)
1. 前言 由于后面还有很多题型要写,贪心算法目前可能就到此为止了,上一篇博客的地址为 LeetCode解题记录(贪心算法)(一) 下面正式开始我们的刷题之旅 2. 贪心 763. 划分字母区间(中等 ...
- 【ybtoj】贪心算法例题
[基础算法]第二章 贪心算法 例一 奶牛晒衣服 题目描述 有n件衣服,第i件衣服的湿度为h. 在自然条件下,每件衣服每分钟都可以自然晒干A点湿度. 在烘干机作用下,可以选择一件衣服,用一分钟的时间晒干 ...
- LeetCode算法训练-贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和
欢迎关注个人公众号:爱喝可可牛奶 LeetCode算法训练-贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和 前置知识 贪心算法核心是找局部最优解,通过局部最优推导出全局最优 Lee ...
- leetcode 贪心算法
贪心算法中,是以自顶向下的方式使用最优子结构,贪心算法会先做选择,在当时看起来是最优的选择,然后再求解一个结果的子问题. 贪心算法是使所做的选择看起来都是当前最佳的,期望通过所做的局部最优选择来产生一 ...
- Leetcode题目55.跳跃游戏(贪心算法-中等)
题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出: ...
- 【Leetcode】买卖股票-贪心算法
题目: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必 ...
- 【算法】数据结构与算法基础总览(中)——刷Leetcode等算法题时一些很实用的jdk辅助方法锦集
最近重新学习数据结构与算法以及刷leetcode算法题时,发现不少jdk自带的方法可以提升刷题的效率.这些小技巧不仅仅对刷算法题带来便利,对我们平时开发也是很有帮助的.本文以java语言为基础,记录了 ...
随机推荐
- 自己动手从零写桌面操作系统GrapeOS系列教程——14.屏幕显示原理与文本模式
学习操作系统原理最好的方法是自己写一个简单的操作系统. 一.屏幕显示原理 电脑显示器屏幕是由很多很小的像素组成的.每个像素就像是一个小灯泡,在屏幕上一排一排的整齐排列着.只要能控制每个像素的颜色就能显 ...
- wsl 中 docker-compose 搭建 kafka 集群出现的外部访问错误
在 wsl 中用 docker-compose 搭建了一台 zookeeper + 三台 broker 的 kafka 集群,使用的镜像是 bitnami/kafka,在按照镜像文档运行容器后,发现运 ...
- NoSQL之 Redis配置与优化
目录 一.缓存概念 1.1 系统缓存 1.1.1buffer与cache 1.2 缓存保存位置及分层结构 1.2.1 DNS缓存 1.2.2 应用层缓存 1.2.3数据层缓存 1.2.4 硬件缓存 二 ...
- ES5新增数组常见方法(indexof/forEach/map/filter)
新增的数组常见方法:以下说明中,红色为必选参数,蓝色为可选参数 1.indexOf(data,start); 用于返回某个数组或者字符串中规定字符或者字符串的位置: var arr = [" ...
- 红队实战靶场ATT&CK(二)
一.环境配置 web靶机有一块NAT网卡,只需要修改这块NAT网卡的网关,IP改成与攻击机器同网段就可以了 到web靶机中C:/Oracle/Middleware/user_projects/doma ...
- Jmix 如何将外部数据直接显示在界面?
企业级应用中,通常一个业务系统并不是孤立存在的,而是需要与企业.部门或者是外部的已有系统进行集成.一般而言,系统集成的数据和接口交互方式通常有以下几种: 文件传输:通过文件传输的方式将数据传递给其他系 ...
- [MySQL]innodb_flush_log_at_trx_commit与sync_binlog
1 innodb_flush_log_at_trx_commit 辨析 innodb_flush_log_at_trx_commit = 0 : 每秒将日志缓冲区写入log file,并同时flush ...
- 【Diary】CSP-S2 2021 游记 & NOIP 备赛发疯日记
Day 0 两个极端的回跳. .....不行啊. 我快输不起了........... ------------------------------- 早上被生物钟强行唤醒,逼自己懒床到6:40. 弹琴 ...
- kali装机 安装输入法 修改国内源
1-先配置国内源官方kali源 vim /etc/apt/sources.list 插入如下源 deb http://mirrors.aliyun.com/kali sana main non-fre ...
- Android 事件分发机制源码分析
if(MotionEvent.ACTION_DOWN || mFirstTouchTarget != null){ //初次的down事件到来的时候,只有父view具有决定事件是否拦截的权利.因为此时 ...