最多能完成排序的块 II || 刷题打卡

169 阅读2分钟

题目:

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

解题思路

在我们开始解题时候,我们需要明确的核心问题示,就是如何判断数组可不可以拆分,这里我们采用遍历的方法来遍历整个数组,通过数字之和与排序过后的数组进行对比,来判断有当前数组是否可拆,以及可以拆几次。

滑动窗口解法

/**
 * @param {number[]} arr
 * @return {number}
 */
var maxChunksToSorted = function (arr) { // arr = [2, 1, 3, 4, 4]
  
    const sortArr = [...arr].sort((a, b) => a - b); // [1,2,3,4,4]

    let count = 0,
        sum1 = 0,
        sum2 = 0;

    for (let i = 0; i < arr.length; i++) {
        sum1 += arr[i]; // 加上原数组的每一位 
        sum2 += sortArr[i]; // 加上排序后的数组的每一位
        // sunm1每次的值每次计算 2 + 1 + 3 + 4 + 4
        // 分别为 2,3,6,10,14
        // sumn2每次的值每次计算 1 + 2 + 3 + 4 + 4
        // 分别为 1,3,6,10,14

        if (sum1 === sum2) { // 故在和为361014时候相等,就会有4中可以拆的方法
            count++;
        }
    }

    return count;
};

”本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情