Leetcode 769 最多能完成排序的块

数组arr是[0, 1, ..., arr.length - 1]的一种排列,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。

我们最多能将数组分成多少块?

示例 1:

输入: arr = [4,3,2,1,0]
输出: 1
解释:
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [4, 3], [2, 1, 0] 的结果是 [3, 4, 0, 1, 2],这不是有序的数组。
示例 2:

输入: arr = [1,0,2,3,4]
输出: 4
解释:
我们可以把它分成两块,例如 [1, 0], [2, 3, 4]。
然而,分成 [1, 0], [2], [3], [4] 可以得到最多的块数。
注意:

arr 的长度在 [1, 10] 之间。
arr[i]是 [0, 1, ..., arr.length - 1]的一种排列。
通过次数13,285提交次数22,655

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-chunks-to-make-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目分析

为了满足题目中的要求,每个块与块之间应该满足这样的关系:

相邻的块A、B,A块的最大值小于B块的最小值。

在实际操作的过程中,为了要取到尽可能多的块,从左向右遍历元素,记录前一个块的最大元素,若下一个元素大于这个元素,那么该元素单独成块,但注意,该元素只是可能,包括前面的块都只是可能成为独立的块。因为后面可能会有比前面所有元素都小的元素存在,那么从第一个元素到这个元素都要变成一个独立的块。

所以我们在处理当前元素比前面元素小的时候就不得不同时处理,前面已经分好块的最大值会不会小于当前元素?

其实思路很简单,但是我想到之后觉得非常麻烦,因为要记录那么多最大值,我一度认为这种方法很“蠢”,后来看到题解里一位前辈的单调栈解法,惊为天人,实在是太炫酷了。

因为前面分块只需要记录最大值,所以这位前辈用一个单调递增栈记录下所有可能出现的分块的最大值,以该最大值代表一个可能的分块如果当前遍历到的元素比栈顶元素小,那么这个元素有可能覆盖掉前面的分块!

所以遍历栈顶下面的所有元素,弹出比当前元素还要大的元素,就代表这个元素代表的分块不能存在了!最后在加入刚刚的栈顶元素,以代表一个新的、更长的分块。

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int temp;
        stack<int> book;
        book.push(arr[0]);
        for(int i = 1;i<arr.size();i++){
            if(arr[i]>book.top()){
                book.push(arr[i]);
                continue;
            }
            temp = book.top();
            while(!book.empty()&&book.top()>arr[i]){
                book.pop();
            }
            book.push(temp);
        }
        return book.size();
    }
};

猜你喜欢

转载自blog.csdn.net/qq_37637818/article/details/121384549