数组的最大子组,以便可以对其进行独立排序

时间:2018-01-10 22:46:18

标签: arrays algorithm sorting

对于一个数组,我需要找到可以创建的最大子组数,这样当所有子组被单独排序然后依次顺序放置时,整个数组就会被排序。

例如: 数组[1, 5, 4, 9, 8, 7, 12, 13, 14]

可以形成的最大组数 6

[1], [5, 4], [9, 8, 7], [12], [13], [14]

如果我们要独立排序内部元素然后将这些组放在一起,我们就会得到一个排序数组。

另一个示例是[4, 3, 2, 6, 1],其中可以形成的最大组仅 1 (数组本身)

请注意,数组的所有元素都是不同。我写的程序是用以下伪代码写的 -

1. Save all elements of array A into hashmap with the element value A[i] as key 
   and index i as value
2. Sort array A.
3. Initialize groupCount = 0, startIndex = -1;
3. For every element, check from hashmap if its original index is 
   greater than **startIndex**. If it is greater, increment groupCount 
   and set startIndex = original index of element i.
4. Finally return groupCount;

这个逻辑无法在很多测试用例上运行。你能帮我弄清楚什么是最佳逻辑吗?

2 个答案:

答案 0 :(得分:3)

请注意,只要它包含的元素集与排序数组中相应位置上显示的元素集相同,就可以结束当前组。

上述想法可以直接在 O (N ^ 2)中实现,但在以下观察中转换它很有用,更容易有效实现(可能需要花一点时间才能实现为什么上述陈述意味着下一个):

  • 最大组数等于索引数 k ,这样序列中的第一个 k 元素就是最小的 k ones。

这更容易实现,因为为了检查最小的 k + 1项是否恰好是原始数组中的第一个 k + 1个,我们可以只查看最小的 k + 1项中最大的原始索引。如果这个最大的索引是 k ,那么我们必须在这些第一个位置上发生索引0,1,... k 的集合。

下面的伪代码详述了这种方法。时间复杂度为 O (N log(N)),由排序步骤确定。

1. Save all elements of array A into a hashmap with the element value A[i] as key 
   and index i as value
2. Sort array A.
3. Initialize groupCount = 0, maxIndex = -1;
4. For k = 0 to N,
       check from hashmap the original index i, of A[k]
       maxIndex = max(i, maxIndex)
       if maxIndex == k then increment groupCount
5. Finally return groupCount;

答案 1 :(得分:1)

您的方法几乎正确。只要原始索引大于起始索引,就会增加组计数。在许多情况下,这将失败,例如:5 6 3 4

使用您的代码

  • 在上面的数组中(即5 6 3 4),它将检查5的原始索引,该索引应该是 2 (按排序顺序)&将组计数增加到1,同时将起始索引设置为2
  • 当它检查原始索引6应该是 3 (按排序顺序)时,它会增加组Count( 2 ),因为它的索引更大比起始指数(即2)。这是不正确的,因为答案是 1 !!。

改进

当您遇到6时,您应该将起始索引从2更改为3而不更改组Count&当开始索引=原始索引时,应该增加 组的数量。

这是我的代码 O(NlogN)复杂性:

#include <bits/stdc++.h>
using namespace std;

int maxSubGroups(vector<int>arr){
    int n=arr.size();
    vector<int>sortedArr = arr;
    sort(sortedArr.begin(), sortedArr.end());
    map<int,int>m;
    for(int i=0;i<sortedArr.size();i++)
        m[sortedArr[i]]=i;
    int maxGroups = 0, maxIndex=0;
    for(int i=0;i<n;i++){
        maxIndex = max(maxIndex, m[arr[i]]);
        if(maxIndex == i)
            maxGroups++;
    }
    return maxGroups;
}

int main() {
    vector<int>arr = {1, 5, 4, 9, 8, 7, 12, 13, 14};
    int maxGroups = maxSubGroups(arr);
    cout<<maxGroups; // 6
    return 0;
}

Live Code