题目概述
解题思路
这道题首先提示我们:有O(n)时间复杂度的解法。也就是说,只需要常数次地遍历数组即可。
观察这个数组,我们可以发现,关键在于找到第一个和最后一个需要调换位置的数的序号。这该怎么找呢?
观察发现:假设数组A前i个元素的最大值为,如果A[i+1] < ,则该元素必定要调换顺序;如果A[i+1] == ,则要根据之后的结果判断。同样假设数组A后j个元素的最小值为,如果A[j-1] > ,则该元素必定要调换顺序;如果A[j-1] == ,则要根据之前的结果判断。这样我们先顺序遍历一遍数组,找到第一个和最后一个可能发生位置调换的地方fir_sta和fir_end;然后倒序遍历一遍数组,找到类似的两处地方sec_sta和sec_end,则需要调换的位置就是:从min(fir_sta, sec_sta)到max(fir_end, sec_end)。
方法性能
示例代码
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums)
{
int sta_idx = nums.size(), end_idx = 0, temp_max = -100001, temp_min = 100001;
bool sig = true;
for(int i = 0; i < nums.size(); ++i)
{
if(nums[i] < temp_max)
{
if(sig)
{
sta_idx = i - 1;
sig = false;
}
end_idx = i;
}
else
temp_max = nums[i];
}
sig = true;
int idx_end = 0, idx_sta = nums.size();
for(int i = nums.size() - 1; i >= 0; --i)
{
if(nums[i] > temp_min)
{
if(sig)
{
idx_end = i + 1;
sig = false;
}
idx_sta = i;
}
else
temp_min = nums[i];
}
end_idx = max(end_idx, idx_end);
sta_idx = min(sta_idx, idx_sta);
return (end_idx <= sta_idx) ? 0 : (end_idx - sta_idx + 1);
}
};