题目
题目链接:面试题 16.16. 部分排序
思路
部分排序思路:要找未排好序的数,其实就是找它的逆序对;
如何找逆序对呢?如何确认逆序对的范围呢?
逆序对就是相对于原来的排序顺序是相反的,比如原来是从左到右升序,那么你从左到右如果右降序的,那么就是逆序对了
确认最右边逆序对的范围?确认左边逆序对的范围?
确认最右边的:
数组从左到右是增大的,我们用cur遍历数组,找到其最大的一个值max,用nums[cur]和它比较;
只要nums[cur] > max 还要大,那么就更新max,同时cur继续往前走;
只要nums[cur] < max ,那么说明开始发现逆序对了,因为我们原来排序的位置是从小到大,但是遍历却发现有小的数字出现,这表明有逆序对;
发现逆序对之后,就先记录改位置,由于还没有确认是最右边的逆序对,所以还需要继续遍历;
确认最左边的:
思路和确认最右边的一幕一样,只不过遍历不是从数组1开始,而是从数组后面开始,不是找最大值,而是最小值;
初始条件:
结束条件:
class Solution {
public:
vector<int> subSort(vector<int>& nums) {
if (nums.size() == 0) return vector<int>{-1, -1};
int max = nums[0]; //假设第一个最大,我们就可以从数组下标为1的位置开始遍历
int right = -1;
for (int cur = 1; cur < nums.size(); cur++)
{
if (nums[cur] >= max)
{
max = nums[cur];
}
else
{
right = cur;
}
}
int min = nums[nums.size()-1];//假设最后一个最大,我们就可以从数组下标为倒数第二个的位置开始遍历
int left = -1;
for (int cur = nums.size()-2; cur >=0; cur--)
{
if (nums[cur] <= min)
{
min = nums[cur];
}
else //若nums[cur] > min说明有逆序对啦,那么就跟新left
{
left = cur;
}
}
return vector<int>{left, right};
}
};