1,题目要求
Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.
You need to find the shortest such subarray and output its length.
Example 1:
- Input: [2, 6, 4, 8, 10, 9, 15]
- Output: 5
- Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.
Note:
- Then length of the input array is in range [1, 10,000].
- The input array may contain duplicates, so ascending order here means <=.
给定一个整数数组,您需要找到一个连续的子数组,如果您只按升序对该子数组进行排序,那么整个数组也将按升序排序。
您需要找到最短的子阵列并输出其长度。
例1:
- 输入:[2,6,4,8,10,9,15]
- 输出:5
- 说明:您需要按升序对[6,4,8,10,9]进行排序,以使整个数组按升序排序。
注意:
1.然后输入数组的长度在[1,100]范围内。
2.输入数组可能包含重复项,因此这里的升序表示<=。
2,题目思路
对于这道题,是判断一个数组中,需要排序的部分的长度。
具体含义,即对于数组:
1,2,3,4,5
这个数组是不需要排序的,则长度为0;
对于数组:
1,3,2,4,5,7,6,8
这个数组中,3,2,4,5,7,6是需要排序的,即需要排序的长度为6。
在实现上,我们定义两个变量begin和end,用来追踪需要排序的数组的开始和结束的位置。
定义maxVal记录从前往后遍历时的当前最大值;
定义minVal记录从后往前遍历时的当前最小值。
当我们同时从前往后、从后往前同时进行遍历:
- 从前往后遍历时,每次都先对maxVal进行更新,即maxVal= max(maxVal, nums[i]),如果是有序的,那么可以得到的是,maxVal始终等于nums[i]。而如果是无序的,那么可以得到的是,maxVal不等于nums[i],因为nums[i]比前面的最大值小。这时,我们就记录end为i,因为我们是从前往后遍历的。end会一直进行更新,直到有nums[i]的值比maxVal的值更大,即在nums[i]处恢复了有序。
- 从后往前遍历,与从前往后遍历是相类似的。只不过max变成了min,更新begin。
而对于begin和end,因为我们最后的返回值是end - begin + 1,而如果数组是有序的,那么begin和end的值都不会被修改,因此,给begin的初值设为-1,end的初值设为-2,,保证在数组有序时返回值为0。
3,代码实现
static const auto s = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
if(nums.size() == 0)
return 0;
int begin = -1;
int end = -2;
int n = nums.size();
int maxVal = nums[0], minVal = nums[n-1];
for(int i = 1;i < n;i++)
{
maxVal = max(nums[i], maxVal);
minVal = min(nums[n-1-i], minVal);
if(nums[i] != maxVal)
end = i;
if(nums[n-1-i] != minVal)
begin = n-1-i;
}
return end - begin + 1;
}
};