1. 前言

由于后面还有很多题型要写,贪心算法目前可能就到此为止了,上一篇博客的地址为

LeetCode解题记录(贪心算法)(一)

下面正式开始我们的刷题之旅

2. 贪心

763. 划分字母区间(中等)

题目链接

思路

想切割,要有首尾两个指针,确定了结尾指针,就能确定下一个切割的开始指针。

遍历字符串,如果已扫描部分的所有字符,都只出现在已扫描的范围内,即可做切割。

注意 : 贪心的思想为,只要是扫描过的字符,都出现在我扫描的范围之类,我就切割,不去考虑其他的条件,这样能保证切割的数量最多

代码实现思路

  • result 用来保存结果
  • start end,片断的首尾指针
  • map 存放每一个字符的最远位置

首先通过一个map,记录了每个字符的最远的位置,接下来遍历字符串,end是用来记录,当前已经扫描的字符串的最远的出现的位置,如果当前的位置,等于扫描的字符串的最远位置,则,可以证明,到达了切割的条件,然后切割,存到result里

class Solution {
public:
vector<int> partitionLabels(string S) {
vector<int> result;
unordered_map<char, int> map; //记录char c 和其最后出现位置的 map
int start = 0, end = 0;
// 初始化map,记录每一个字符的最后位置
for (int i = 0; i < S.size(); i ++) {
map[S[i]] = i;
}
for (int i = 0; i < S.size(); i ++) {
end = max(end, map[S[i]]);//记录已扫描字符的最后一次出现的位置
if (i == end) {//说明后面的片段没有出现重复的字母了
result.push_back(end - start + 1);//记录结果
start = i + 1;
}
}
return result;
}
};

406. 根据身高重建队列(中等)

解题思路

贪心算法:按照身高从高到低进行排序,矮的放后面,因为矮的即使放在了高的前面,也不会对之前高的产生影响;但高的放在前面,对矮的结果就会产生影响了。

重写 compare() 方法:身高相同,按照个数升序排序;身高不同,按照身高降序排序。

public int compare(int[] o1, int[] o2) {

    // 先按身高降序,若身高相同则按 k 值升序。
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0];
}

第二个数字作为索引位置,把数组放在目标索引位置上,如果原来有数了,会往后移。(在一个 ListList 中的指定位置插入一个元素,当前指定位置的元素会往后面移动一个位置。)

遍历排序后的数组,根据 K 插入到 K 的位置上。

class Solution {

    public int[][] reconstructQueue(int[][] people) {

        int n = people.length;
int m = people[0].length;
if (n == 0 || m == 0) return new int[0][0]; Arrays.sort(people, new Comparator<int[]>() { @Override
public int compare(int[] o1, int[] o2) { // 先按身高降序,若身高相同则按 k 值升序。
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0];
}
}); // 遍历排序后的数组,根据 K 插入到 K 的位置上。
List<int[]> list = new ArrayList<>();
for (int[] i : people) { list.add(i[1], i);
}
return list.toArray(new int[list.size()][2]);
}
}

665. 非递减数列

题目链接

给你一个长度为 n 的整数数组,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。

我们是这样定义一个非递减数列的: 对于数组中任意的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。

示例 1:

输入: nums = [4,2,3]

输出: true

解释: 你可以通过把第一个4变成1来使得它成为一个非递减数列。

示例 2:

输入: nums = [4,2,1]

输出: false

解释: 你不能在只改变一个元素的情况下将其变为非递减数列。

提示:

1 <= n <= 10 ^ 4

10 ^ 5 <= nums[i] <= 10 ^ 5

题解:

贪心算法

本题是要维持一个非递减的数列,所以遇到递减的情况时(nums[i] > nums[i + 1]),要么将前面的元素缩小,要么将后面的元素放大。

但是本题唯一的易错点就在这,

如果将nums[i]缩小,可能会导致其无法融入前面已经遍历过的非递减子数列;

如果将nums[i + 1]放大,可能会导致其后续的继续出现递减;

所以要采取贪心的策略,在遍历时,每次需要看连续的三个元素,也就是瞻前顾后,遵循以下两个原则:

需要尽可能不放大nums[i + 1],这样会让后续非递减更困难;

就是能不放大就不放大,尽量与前面持平

如果缩小nums[i],但不破坏前面的子序列的非递减性;

算法步骤:

遍历数组,如果遇到递减:

还能修改:

修改方案1:将nums[i]缩小至nums[i + 1];

这个方案是,用i-1,i,i+1,来表示三个数的位置,其中i是我们发现大于i+1的数,那么当i+1大于i-1的时候,我们应该将i缩小至i+1,为什么呢,你想啊,你右边的数比你小,你左边的数比你小,但是呢,你右边的数比你左边的数高,你是不是只需要和你右边的一样高,就能保持非递减?如果你不这样,你让右边的数增加,这就违反了上面的第一条原则:需要尽可能不放大nums[i + 1],这样会让后续非递减更困难,因为这种情况,我们的选择是缩小i

修改方案2:将nums[i + 1]放大至nums[i];

这种情况是什么呢,与上一种相反,你左边右边的数都比你小,但是你右边的数比你左边的数要小,这个时候我们就应该将右边的数放大,放大至nums[i],也就是你的大小,这种情况下是没有争论的,只能将右边的数放大,不明白的同学可以自己在纸上画一画

如果不能修改了:直接返回false;

这个代码需要修改两个地方,显然不符合题目要求,返回false

代码如下

flag 代表修改机会,因为只有一次,所以用掉了,flag就变成false

class Solution {
public:
bool checkPossibility(vector<int>& nums)
{
if (nums.size() == 1) return true;
bool flag = nums[0] <= nums[1] ? true : false; // 标识是否还能修改
// 遍历时,每次需要看连续的三个元素
for (int i = 1; i < nums.size() - 1; i++)
{
if (nums[i] > nums[i + 1]) // 出现递减
{
if (flag) // 如果还有修改机会,进行修改
{
if (nums[i + 1] >= nums[ i - 1])// 修改方案1
nums[i] = nums[i + 1];
else // 修改方案2
nums[i + 1] = nums[i];
flag = false; // 用掉唯一的修改机会
}
else // 没有修改机会,直接结束
return false;
}
}
return true;
}
};

执行结果

3. 总结

对不起各位,我算法这块更新的实在是太慢了,不过最近真的很忙很忙,当然有时候我也会娱乐一下,没有做到自律,下个星期我还准备开始写计算机网络和操作系统的专栏,所以算法这块,我尽量多写(其实我就是懒,有时候晚上回家真的好累,不想写算法题,,,,)

总之,下个星期,继续努力,与昨天的自己比较!

LeetCode解题记录(贪心算法)(二)的更多相关文章

  1. LeetCode解题记录(贪心算法)(一)

    1. 前言 目前得到一本不错的算法书籍,页数不多,挺符合我的需要,于是正好借这个机会来好好的系统的刷一下算法题,一来呢,是可以给部分同学提供解题思路,和一些自己的思考,二来呢,我也可以在需要复习的时候 ...

  2. C#LeetCode刷题-贪心算法

    贪心算法篇 # 题名 刷题 通过率 难度 44 通配符匹配   17.8% 困难 45 跳跃游戏 II   25.5% 困难 55 跳跃游戏   30.6% 中等 122 买卖股票的最佳时机 II C ...

  3. [leetcode解题记录]Jump Game和Jump Game II

    Jump Game Given an array of non-negative integers, you are initially positioned at the first index o ...

  4. Leetcode解题记录

    尽量抽空刷LeetCode,持续更新 刷题记录在github上面,https://github.com/Zering/LeetCode 2016-09-05 300. Longest Increasi ...

  5. LeetCode解题记录(双指针专题)

    1. 算法解释 双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务.也可以延伸到多个数组的多个指针. 若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域 ...

  6. LeetCode 135 Candy(贪心算法)

    135. Candy There are N children standing in a line. Each child is assigned a rating value. You are g ...

  7. 「面试高频」二叉搜索树&双指针&贪心 算法题指北

    本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...

  8. 基于贪心算法的几类区间覆盖问题 nyoj 12喷水装置(二) nyoj 14会场安排问题

    1)区间完全覆盖问题 问题描述:给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间),求最少使用多少条线段可以将整个区间完全覆盖 样例: 区间长度8,可选的覆盖线段[2,6],[1, ...

  9. 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 ...

随机推荐

  1. Python+Selenium自动化-安装模块和浏览器驱动操作方法

    Python+Selenium自动化-安装模块和浏览器驱动操作方法 1.安装模块文件 pip install selenium 2.安装浏览器驱动 我们主要用的浏览器驱动有chrome浏览器.fire ...

  2. 项目记事【Git】:git pull 出错 error: cannot lock ref 'refs/remotes/origin/feature/hy78861': is at d4244546c8cc3827491cc82878a23c708fd0401d but expected a6a00bf2e92620d0e06790122bab5aeee01079bf

    今天 pull 代码的时候碰到以下问题(隐去了一些公司敏感信息): XXX@CN-00012645 MINGW64 /c/Gerrard/Workspace/XXX (master) $ git pu ...

  3. .net core 使用阿里云分布式日志

    前言 好久没有出来夸白了,今天教大家简单的使用阿里云分布式日志,来存储日志,没有阿里云账号的,可以免费注册一个 开通阿里云分布式日志(有一定的免费额度,个人测试学习完全没问题的,香) 阿里云日志地址: ...

  4. 永远的Ace 团队作业4—团队项目需求建模与系统设计(1)

    项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST/ 这个作业要求链接 https://www.cnblogs.com/nwnu-da ...

  5. windows 设置nginx开机自启动

    将Nginx设置为Windows服务 需要借助"Windows Service Wrapper"小工具,项目地址: https://github.com/kohsuke/winsw ...

  6. java后端知识点梳理——java集合

    集合概览 Java中的集合,从上层接口上看分为了两类,Map和Collection.Map是和Collection并列的集合上层接口,没有继承关系. Java中的常见集合可以概括如下. Map接口和C ...

  7. python 数据写入json文件时中文显示Unicode编码问题

    一.问题描述 import json dir = { '春晓':'asfffa', '春眠不觉晓' : '处处闻啼鸟', '夜来风雨声' : 56789, 'asdga':'asdasda' } fp ...

  8. Java面试指北!13个认证授权常见面试题/知识点总结!| JavaGuide

    大家好,我是 Guide哥!端午已过,又要开始工作学习啦! 我发现有很多小伙伴对认证授权方面的知识不是特别了解,搞不清 Session 认证.JWT 以及 Cookie 这些概念. 所以,根据我根据日 ...

  9. 数位dp从会打模板到不会打模板

    打了几个数位$dp$,发现自己除了会打模板之外没有任何长进,遇到非模板题依然什么都不会 那么接下来这篇文章将介绍如何打模板(滑稽) 假设我们要处理$l----r$ 采用记忆化搜索的方式,枚举$< ...

  10. cmake使用笔记,一些常用的命令

    我的工程目录如下: │ CMakeLists.txt ├─cmake_tutorial │ CMakeLists.txt │ cmake_tutorial.cpp │ cmake_tutorial.h ...