题意:提取一个连续的子数组,使其剩下的是有序数组
思路:
(1)将原始数组进行sort排序,从双端向中间逼近,如有不一致值,则为数组的开始和结尾位置
时间复杂度:o(nlogn);空间复杂度:o(n)
int findUnsortedSubarray(vector<int>& nums) {
if (nums.size() <= 1) {
return 0;
}
if (nums.size() == 2) {
if (nums[0] > nums[1]) {
return 2;
}
return 0;
}
vector<int> temp;
//copy nums数组到temp数组中
temp.insert(temp.begin(), nums.begin(), nums.end());
sort(temp.begin(), temp.end());
int start = 0, end = 0;
for (int i = 0; i < temp.size(); i++) {
if (temp[i] != nums[i]) {
start = i;
break;
}
}
for (int i = temp.size() - 1; i >= 0; i--) {
if (temp[i] != nums[i]) {
end = i;
break;
}
}
if (start == 0 && end == 0) {
return 0;
}
return end - start + 1;
}
ps:代码比较繁琐,将nums.size() == 2去掉;
int findUnsortedSubarray(vector<int>& nums) {
if (nums.size() <= 1) {
return 0;
}
vector<int> temp;
//copy nums数组到temp数组中
temp.insert(temp.begin(), nums.begin(), nums.end());
sort(temp.begin(), temp.end());
int start = 0, end = 0;
for (int i = 0; i < temp.size(); i++) {
if (temp[i] != nums[i]) {
start = i;
break;
}
}
for (int i = temp.size() - 1; i >= 0; i--) {
if (temp[i] != nums[i]) {
end = i;
break;
}
}
if (start == 0 && end == 0) {
return 0;
}
return end - start + 1;
}
(2)尝试优化时间复杂度和空间复杂度,达到最优
思想:一个数组可以拆分为ABC,A和C为有序数组,B为无序数组;特点:B中数组元素都大于A中数组元素,都小于C中数组元素;则通过左右遍历即可找到最大值和最小值,而破坏这种平衡的就为无序数组的左右边界;并且,本题只需要确定无序数组的左右边界可以,无序数组里面有序的子数组可以暂不考虑(如:2,6,7,8,3,10)
如【2,6,4,10,8,15】
end = 0 max = 2,右边界=0 | end = 0 max = 6,右边界=0 | end = 2 max = 6,右边界=2 | end = 2 max=10,右边界=2 | end = 4 max=10,右边界=4 | end = 4 max=15,右边界=4 |
2 | 6 | 4 | 10 | 8 | 15 |
start = 2 min = 2 左边界=1 | start = 1 min = 4 左边界=1 | start = 3 min = 4 左边界=3 | start = 3 min = 8 左边界=3 | start = 0 min = 8 左边界=0 | start = 0 min = 15 左边界=0 |
上面表格从左到右执行,下面表格从右到左执行;
int findUnsortedSubarray(vector<int>& nums) {
if (nums.size() <= 1) {
return 0;
}
if (nums.size() == 2) {
if (nums[0] > nums[1]) {
return 2;
}
return 0;
}
int start = 0, end = 0, max_value = INT_MIN, min_value = INT_MAX;
//获取右边界
max_value = std::max(nums[0], max_value);
for (int i = 1; i < nums.size(); i++) {
if (nums[i] < max_value) {
end = i;
}
if (max_value < nums[i]) {
max_value = nums[i];
}
}
//获取左边界
min_value = std::min(nums[nums.size() - 1], min_value);
for (int i = nums.size() - 2; i >= 0; i--) {
if (nums[i] > min_value) {
start = i;
}
if (min_value > nums[i]) {
min_value = nums[i];
}
}
if (start == 0 && end == 0) {
return 0;
}
return end - start + 1;
}