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. Pass算子python 函数

    Pass算子python 函数 函数 函数是代码的一种组织形式 函数应该能完成一项特定的工作,而且一般一个函数只完成一项工作 有些语言,分函数和过程两个概念,通俗解释是,有返回结果的是函数,无返回结果 ...

  2. Action4D:人群和杂物中的在线动作识别:CVPR209论文阅读

    Action4D:人群和杂物中的在线动作识别:CVPR209论文阅读 Action4D: Online Action Recognition in the Crowd and Clutter 论文链接 ...

  3. 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练

    计图(Jittor) 1.1版本:新增骨干网络.JIT功能升级.支持多卡训练 深度学习框架-计图(Jittor),Jittor的新版本V1.1上线了.主要变化包括: 增加了大量骨干网络的支持,增强了辅 ...

  4. Java真的是白天鹅

    前言 我最近越来越真切的感受到,Java真的是白天鹅. 这真的是一种羡慕嫉妒恨的感受. 今天和一个Java技术Leader聊天,我告诉他敏捷开发是以人为本,他居然跟我说敏捷开发在行业内有规范,规范是死 ...

  5. ContOS8 配置MariaDB

    导语: 该篇文章主要记录ContOS8安装MariaDB后的一些配置内容,若想要详细了解安装过程请移步至上一篇博文! 正文: 首先对MariaDB进行相关的简单配置 使用mysql_secure_in ...

  6. 总结springboot开启mybatis驼峰命名自动映射的三种方式

    方式一:通过springboot的配置文件application.yml mybatis: configuration: map-underscore-to-camel-case: true 此方式是 ...

  7. DHCP:IP 并非与生俱来

    初识 DHCP 众所周知,因特网上的每台设备都规定了其全世界唯一的地址,也就是说 "IP 地址",正是由于有了 IP 地址,才保证了用户在连网的计算机上操作时,能够高效而且方便地从 ...

  8. 【vim】常用总结

    简介 什么是vim? Linux下两大编辑神器之一 vim Linux/Unix下使用最多的编辑器 vi的改进版 可能是最难上手的编辑器之一 为什么要学习vim? 都21世纪了,为什么还需要学习vim ...

  9. docker创建和使用mysql

    container和image是两种不同的概念,image即指存在的镜像,container指docker运行起来后image的实例. 当使用docker kill 把某个正在运行的实例kill掉之后 ...

  10. npm ERR! Unexpected end of JSON input while parsing near '...'解决方法

    npm install时出现npm err! Unexpected end of JSON input while parsing near'...'错误 输入  npm cache clean -- ...