使数组按非递减顺序排列Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
给你一个下标从 0 开始的整数数组 nums 。
在一步操作中,移除所有满足 nums[i - 1] > nums[i] 的 nums[i] ,其中 0 < i < nums.length 。
重复执行步骤,直到 nums 变为 非递减 数组,返回所需执行的操作数。
示例 1:
输入:nums = [5,3,4,4,7,3,6,11,8,5,11]
输出:3
解释:执行下述几个步骤:
- 步骤 1 :[5,3,4,4,7,3,6,11,8,5,11] 变为 [5,4,4,7,6,11,11]
- 步骤 2 :[5,4,4,7,6,11,11] 变为 [5,4,7,11,11]
- 步骤 3 :[5,4,7,11,11] 变为 [5,7,11,11]
[5,7,11,11] 是一个非递减数组,因此,返回 3 。
示例 2:
输入:nums = [4,5,7,7,13]
输出:0
解释:nums 已经是一个非递减数组,因此,返回 0 。
提示:
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 109
# 思路
/**
* [9 1 2 4 3 5 5]
*
* 9
* -----------------------------6
* ------------------------5
* -------------4
* -------------------3
* --------2
* ----1
*
*---------------------------------
* 单调递减队列
*到 1 的时候 9 在队列中 所以 1是 需要被删除的 时间点为 1
*到 2 的时候 9 1 在队列中,要删除2需要先删除1, 时间点为 1 t(1)+1
*到 4 的时候 9 2 在队列中,要删除4需要先删除2, 时间点为 2 t(2)+1
*到 3 的时候 9 4 在队列中,要删除3不需要先删除其他的值,所以删除3的时间点为1
*到 5 的时候 9 4 3 在队列中,要删除5 需要先删除 4,3,所以删除5的时间点为t(4)+1
*到 6 的时候 9 5 在队列中,要删除6 需要先删除 5,所以删除6的时间点为t(5)+1
*/
# 解法
class Solution {
public int totalSteps(int[] nums) {
int ans = 0;
Stack<int[]> stack = new Stack<>();
for (int num : nums) {
//要删除当前num 的时间点
int maxT = 0;
//单调递减队列
while (!stack.isEmpty() && stack.peek()[0] <= num) {
//左边小于等于num的值都需要在num被删除之前删掉,此时maxT 为删掉左边这些小与等于num的数的最大时间
maxT = Math.max(maxT, stack.pop()[1]);
}
//如果stack 不为空,所有还有左边还有比num值大的情况,表示num需要被删除,如果为空,说明num不用删除
if (!stack.isEmpty()) {
maxT++;
}
stack.add(new int[]{num, maxT});
ans = Math.max(ans, maxT);
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 总结
- 分析出几种情况,然后分别对各个情况实现