每日一题-23-最短无序连续子数组
给你一个整数数组 nums
,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
请你找出符合题意的 最短 子数组,并输出它的长度。
示例 1:
输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
示例 2:
输入:nums = [1,2,3,4]
输出:0
示例 3:
输入:nums = [1]
输出:0
提示:
1 <= nums.length <= 104
- `-105 <= nums[i] <= 1
**进阶:**你可以设计一个时间复杂度为 O(n)
的解决方案吗?05
1.直接使用暴力的三层循环来实现
2.我们分析可以发现在题目中,我们的目标是一个排序好的字符串,因此就可以直接联想到将一个已经排序好的字符串和原来的字符串做比对,为了提高效率,我们可以利用双指针的思想,分别从头部和尾部同时开始遍历,代码实现如下。
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
vector<int> ans = nums;
sort(ans.begin(),ans.end());
if(ans == nums) return 0;
int i = 0;
int j = nums.size()-1;
while((nums[i]==ans[i] || nums[j]==ans[j]) && i < j){
if(nums[i]==ans[i]){
i++;
}
if(nums[j] == ans[j]){
j--;
}
}
return j - i + 1;
}
};
3.参考leetcode上一个老哥的c++方法:连接
感觉这个方法确实十分的巧妙,很难想到,而且并不是很容易理解。
代码如下
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int n = nums.size();
int mn = nums[n-1], l = n;
for (int i = n - 1; i >= 0; --i) {
if (nums[i] > mn) {
l = i;
}
mn = min(nums[i], mn);
}
int mx = nums[0], r = 0;
for (int i = 0; i < n; ++i) {
if (nums[i] < mx) {
r = i;
}
mx = max(nums[i], mx);
}
return max(r - l + 1, 0);
}
};