768. 最多能完成排序的块 II

58 阅读1分钟

这个问题和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为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] 可以得到最多的块数。 

题解:

  • 方法一:单调栈
var maxChunksToSorted = function (arr) {
    const stack = [];
    for (let cur of arr) {
        // 当前值大于或者等于栈顶元素入栈
        // 也就是说遇到大于当前栈顶值时可分为一个排序块
        if (stack.length == 0 || cur >= stack[stack.length - 1]) {
            stack.push(cur)
        } else {
            // 当遇到小于栈顶元素值时查询当前值属于哪个块内
            // 例如:[3, 2, 1]
            // 3位单独块,当2 < 3时 2属于3的块内2入栈,
            // 同理1 < 3, 1也属于3的块 1也不入栈
            let top = stack.pop()
            while (stack.length && stack[stack.length - 1] > cur) {
                stack.pop()
            }
            stack.push(top)
        }
    }
    return stack.length
};
  • 方法一:滑动窗口

image.png

var maxChunksToSorted = function (arr) {
    // 排序
    const sortArr = [...arr].sort((a, b) => a - b)
    let ans = 0;
    let sum1 = 0, sum2 = 0
    for (let i = 0; i < arr.length; i++) {
        // 累加原数组每一项
        sum1 += arr[i]
        // 累加排序后的数组每一项
        sum2 += sortArr[i]
        // 1、原素组与排序后数组总和相等
        // 2、是原数组进行分块后,每一个分块和排序后的数组中对应的分块数字是一样的
        // 3、既然每个分块中数字是一样的,那它们的和也是一样的了
        // 例如:
        //     原数组:[4, 6, 5, 7, 8]
        //     排序后:[4, 5, 6, 7, 8]
        // 分为4块:
        //     第一块 => 4 第二块 => 6,5 第三块 => 7 第四块 => 8
        if (sum1 == sum2) {
            ans++
        }
    }
    return ans
}

来源:力扣(LeetCode)

链接:leetcode.cn/problems/ma…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。