对于一个数组,我需要找到可以创建的最大子组数,这样当所有子组被单独排序然后依次顺序放置时,整个数组就会被排序。
例如:
数组[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;
这个逻辑无法在很多测试用例上运行。你能帮我弄清楚什么是最佳逻辑吗?
答案 0 :(得分:3)
请注意,只要它包含的元素集与排序数组中相应位置上显示的元素集相同,就可以结束当前组。
上述想法可以直接在 O (N ^ 2)中实现,但在以下观察中转换它很有用,更容易有效实现(可能需要花一点时间才能实现为什么上述陈述意味着下一个):
这更容易实现,因为为了检查最小的 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时,您应该将起始索引从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;
}