力扣 - 768. 最多能完成排序的块II
题目
这个问题和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8。
arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。
我们最多能将数组分成多少块?
示例 1:
输入: arr = [5,4,3,2,1]
输出: 1
解释:
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
示例 2:
输入: arr = [2,1,3,4,4]
输出: 4
解释:
我们可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
注意:
- arr的长度在[1, 2000]之间。
- arr[i]的大小在[0, 10**8]之间。
思路
- 利用单调递增栈来解题
- 遍历数组,将元素存入栈中,再利用max记录当前栈顶的最大值
- 如果遇到比当前栈元素大的值,那么可以直接入栈,因为可以单独分一块;但是如果遇到比当前栈顶元素小的值,那么应该将之前的元素依次出栈,直到遇到小于等于该值的元素停止出栈,然后将max再push入栈(push的这个max就代表了这一个块)
- 例如:有该数组 {1, 1, 3, 4, 5, 2, 6, 7},此时栈为{1, 1, 3, 4, 5}
- 接下来遍历到2了,2比max即5小,所以开始出栈,顺序是:5、4、3,由于1小于2,所以停止出栈,接下来将max(5)入栈,此时栈为:{1, 1, 5}
- 不断遍历,直到数组遍历结束,此时栈中有多少个元素就代表有多少个块了
- 分块规则:后一块元素的最小值大于等于前一块元素的最大值
代码实现
import java.util.LinkedList;
class Solution {
public int maxChunksToSorted(int[] arr) {
LinkedList<Integer> stack = new LinkedList<>();
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (!stack.isEmpty() && arr[i] < max) {
while (!stack.isEmpty() && arr[i] < stack.peek()) {
stack.pop();
}
stack.push(max);
} else {
stack.push(arr[i]);
max = stack.peek();
}
}
return stack.size();
}
}
复杂度分析
- 时间复杂度:\(O(N)\), N 为数组长度
- 空间复杂度:\(O(N)\),N为栈的大小
力扣 - 768. 最多能完成排序的块II的更多相关文章
- Java实现 LeetCode 768 最多能完成排序的块 II(左右便利)
768. 最多能完成排序的块 II 这个问题和"最多能完成排序的块"相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8. arr是一个可能包含 ...
- [Swift]LeetCode768. 最多能完成排序的块 II | Max Chunks To Make Sorted II
This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...
- 力扣(LeetCode)删除排序链表中的重复元素II 个人题解
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 思路和上一题类似(参考 力扣(LeetCode)删除排序链表中的重复元素 个人题解)) 只不过这里需要用到一个前 ...
- Java实现 LeetCode 769 最多能完成排序的块(单向遍历)
769. 最多能完成排序的块 数组arr是[0, 1, -, arr.length - 1]的一种排列,我们将这个数组分割成几个"块",并将这些块分别进行排序.之后再连接起来,使得 ...
- 【力扣】922. 按奇偶排序数组 II
给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数. 对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数:当 A[i] 为偶数时, i 也是偶数. 你可以返回任何满足上述条件的数组 ...
- 【Warrior刷题笔记】力扣169. 多数元素 【排序 || 哈希 || 随机算法 || 摩尔投票法】详细注释 不断优化 极致压榨
题目 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/majority-element/ 注意,该题在LC中被标注为easy,所以我们更多应该关 ...
- 力扣(LeetCode)删除排序链表中的重复元素 个人题解
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 这题思路比较简单,同样是快慢针的思路. 用一个整数类型val对应最新的只出现过一次的那个值, 如果节点的下一个节点的值和这个对应则不做别 ...
- 力扣Leetcode 33. 搜索旋转排序数组
33. 搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值, ...
- [Swift]LeetCode769. 最多能完成排序的块 | Max Chunks To Make Sorted
Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into som ...
随机推荐
- IdentityServer4系列 | 初识基础知识点
前言 我们现在日常生活中,会使用各式各样的应用程序,层出不穷,其中有基于网页浏览方式的应用,有基于手机端的App,甚至有基于流行的公众号和小程序等等,这些应用,我们不仅要实现各个应用的功能之外,还要考 ...
- C# Redis分布式锁 - 单节点
为什么要用分布式锁? 先上一张截图,这是在浏览别人的博客时看到的. 在了解为什么要用分布式锁之前,我们应该知道到底什么是分布式锁. 锁按照不同的维度,有多种分类.比如 1.悲观锁,乐观锁; 2.公平锁 ...
- 《C++ primerplus》第13章练习题
1.对CD类的派生练习.基类CD类存储作者和作品号等信息,派生类Classic额外增加一格"主要作品"的信息.主函数使用拷贝构造函数.按引用传递参数的函数和指针来测试基类和派生类的 ...
- P3118 [USACO15JAN]Moovie Mooving G
P3118 [USACO15JAN]Moovie Mooving G Link 题目描述 Bessie is out at the movies. Being mischievous as alway ...
- AD15使用笔记
AD15使用笔记 1.板内孔开洞 步骤:选中图形->Tools->Convert->Creat Borad Cutout From Selected Primitives;
- 让我们创建屏幕- Android UI布局和控件
下载LifeCycleTest.zip - 278.9 KB 下载ViewAndLayoutLessons_-_Base.zip - 1.2 MB 下载ViewAndLayoutLessons_-_C ...
- Fedora version history --- kernel version
Fedora version history https://en.wikipedia.org/wiki/Fedora_version_history Version (Code name)[ ...
- 测试AAA
程序计数器(线程私有) 程序计数器(Program Counter Register),也有称作为 PC 寄存器.保存的是程序当 前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当 ...
- 多测师讲解python _练习题003_高级讲师肖sir
python 003作业题:# 1.分别打印100以内的所有偶数和奇数并存入不同的列表当中# 2.请写一段Python代码实现删除一个list = [1, 3, 6, 9, 1, 8]# 里面的重复元 ...
- day28 Pyhton 面向对象 继承
1.昨日回顾 类的命名空间 静态属性\动态属性(方法) 对象的命名空间 #对象的属性 #类指针:对象能够通过这个类指针找到类 #静态属性:属于类,多个对象共享这个资源 #尽量用类名来操作静态属性 #对 ...