LeetCode 768:在最大分块排序前的解决方案上构建变体

时间:2020-06-21 22:01:40

标签: javascript arrays algorithm

LeetCode的Max Chunks To Make Sorted II挑战是:

给出整数arr的数组(不一定是唯一的),我们将 将该数组分成若干个“块”(分区),并分别 对每个块进行排序。将它们串联后,结果等于 排序数组。

我们最多可以制作多少块?

示例:

Input: arr = [2, 1, 3, 4, 4]
Output: 4
Explanation:
We can split into two chunks, such as [2, 1], [3, 4, 4].
However, splitting into [2, 1], [3], [4], [4] is the highest number of chunks possible.

algorithm underlying the following solution is(算法和解决方案由名为@benevolent的用户作为注释发布在解决方案页面上。不幸的是,我无法链接到其注释):

如果从arr[0]到(包括)arr[k]的最大数字小于或等于最小数字 从arr[k+1]到末尾的数字,那么我们可以分为两个有效的数字 大块。
为了说明:

   left        right  
[......max] [min......]  

要知道从karr.length-1的最小元素,我们可以 从右到左预先计算。

解决方案:

function maxChunksToSorted(arr) {
  var minRight = Array(arr.length).fill(Number.MAX_SAFE_INTEGER);
  for (var i = arr.length-2; i >= 0; --i) {
    minRight[i] = Math.min(minRight[i+1], arr[i+1]);
  }
  var maxLeft = Number.MIN_SAFE_INTEGER;
  var ans = 0;
  for (var i = 0; i < arr.length; ++i) {
    maxLeft = Math.max(maxLeft, arr[i]);
    if (maxLeft <= minRight[i]) {
      ans += 1
    }
  }
  return ans;
};
console.log("expects: 1", "got:", maxChunksToSorted([5, 4, 3, 2, 1]));
console.log("expects: 4", "got:", maxChunksToSorted([2, 1, 3, 4, 4]));

我的问题

我试图通过“翻转”每个动作来制作上述解决方案的“镜像”(例如,使用min变成max<=变成{{ 1}},依此类推。

我的>实际上是maxArr的镜像(例如,对于minRight,我的[2, 1, 3, 4, 4]maxArr,而原始的[MIN_SAFE_INTEGER, 1, 3, 4, 4]是{{ 1}}),但这显然行不通,而且我也无法对此做出解释。

我的基本问题是什么?

让我强调,我不是在寻找其他可行的解决方案。我想了解我的镜像解决方案出了什么问题,是否有可能制作此镜像,如果没有,这是其根本原因。

minRight

1 个答案:

答案 0 :(得分:0)

这应该可以完成工作:

function chunk(list){
    let sortedList = list.slice();
    sortedList.sort();
    
    var beginIndex = -1; var biggestFound;
    var foundFirst = false; var foundLast = false; 
    
    for(var i = 0; i < list.length; i++){
        if(beginIndex == -1) {
            if(list[i] == sortedList[i]) print(list[i]);
            else {beginIndex = i; biggestFound = list[i];}
        }
        else{
            if(list[i] == sortedList[beginIndex]) foundFirst = true;
            if(list[i] > biggestFound) biggestFound = list[i];
            if(biggestFound == sortedList[i]) foundLast = true;
            if(foundFirst && foundLast){
                print(list.slice(beginIndex, i - beginIndex + 1));                
                foundFirst = false; foundLast = false; beginIndex = -1;
            }           
        }
    }
}

chunk([2,1,3,4,4]);

正如我评论的那样,如果块从位置i开始,它必须包含与已排序数组中位置i对应的元素,并且如果它在位置j处结束,它必须包含已排序数组的索引j中的元素。

当这两个条件都满足时,关闭块并开始一个新的块。

复杂度为O(n lg(n)),其中n是数组的大小。