1. 题目
2. 解题思路
这题理解起来比较绕,这里先简化一下题目。
简单来说,给你一个数组,将它拆分成尽可能多的块儿,每个块儿进行升序后进行连接,最后形成的数组要合原本给你的数组直接进行升序后的结果一样。
例如:
输入: arr = [2,1,3,4,4]
输出: 4
解释:
可以把它分成两块,例如[2, 1]
,[3, 4, 4]
。
然而,分成[2, 1], [3], [4], [4]
可以得到最多的块数。
拆开后的块儿进行ASC–>[1,2], [3], [4], [4]
,进行连接后[1,2,3,4,4]
。和源数组直接进行ASC后的结果一致。
注意:不是说拆的越多越好,比如不能把[2,1]
也拆开了,拆开了的话进行ASC得到[2]
,[1]
,[3]
,[4]
,[4]
,[2],[1]
之间的顺序没办法控制
判断是否是排序块只需要用到该块的?元素最大值?head,我们可以遍历一遍数组 arr ,动态判断到目前数字 num 为止最多能分出多少排序块,并保存每个排序块的最大值 head 。每遍历到下个数字 num ,动态判断前面所有的排序块是否成立,并更新所有排序块:
- 当某排序块 num<head :将此排序块
[A]
与 num 合并,形成新排序块[A | num]
,最大值仍为 head ; - 当某排序块 num>=head :原排序块保留,并新加排序块
[num]
。
最后看看stack中保存了几个排序块的最大值就是答案了。
动态图示例可以参考LC题解:768. 最多能完成排序的块 II - 力扣(LeetCode)
3. 代码
3.1. 注意点
3.2. 完整代码
class Solution {
public int maxChunksToSorted(int[] arr) {
int length = arr.length;
if (length == 0) {
return 0;
}
LinkedList < Integer > stack = new LinkedList < > ();
for (int num: arr) {
if (stack.isEmpty()) {
stack.addLast(num);
continue;
}
int head = stack.getLast();
if (num < head) {
while (!stack.isEmpty() && num < stack.getLast()) {
stack.removeLast();
}
stack.addLast(head);
} else {
stack.addLast(num);
}
}
return stack.size();
}
}