题目描述
给定一个无序数组arr,找到数组中未出现的最小正整数
例如arr = [-1, 2, 3, 4]。返回1
arr = [1, 2, 3, 4]。返回5
[要求]
时间复杂度为O(n),空间复杂度为O(1)
输入描述
第一行为一个整数N。表示数组长度。
接下来一行N个整数表示数组内的数
输出描述
输出一个整数表示答案
示例1
输入:
4
-1 2 3 4
输出:
1
示例2
输入:
4
1 2 3 4
输出:
5
解题思路
以下为左神书中的解题思路,截取下来参考
下面为看到一个博主写的解题过程,本人觉得很清晰
结合两位的思路和方法,下面给出解题代码
实现代码
/*
* @Description: 数组中未出现的最小正整数
* @Author:
* @Date: 2020-11-09 20:30:04
* @LastEditTime: 2020-11-09 20:59:15
* @LastEditors: Please set LastEditors
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> arr(n);
for(int i = 0;i < n;i++){//初始的数组
cin >> arr[i];
}
int left = 0;//左边的索引,将数组分为[0,left]和[left+1,right]
//[0,left]都是满足arr[left] == left + 1
//[left+1,right]表示待处理部分
int right = arr.size() - 1;//表示右边界值
while(left < right){
//1.表示正常情况
if(arr[left] == left + 1){
left++;
}
//2.表示出现不合法情况
//2.1表示在区间[left+1,right]上的数少了一个,因为当前值出现在了[0,left]上
//2.2表示当前值大于整个区间范围,即不在[0,right]的区间范围
//2.3表示当前值出现了重复,则[left+1,right]上的数少了一个
else if (arr[left] <= left || arr[left] > right || arr[ arr[left] - 1 ] == arr[left]){
right--;//范围缩小,故right需要左移
arr[left] = arr[right];//将最后位置上的数放在位置left上(这步不是很懂哎……)
}
//3.表示当前值是一个合法的值,但是没有在理想的位置上,需要进行交换处理
else{
swap(arr[ arr[left] - 1 ], arr[left]);
}
}
cout << left + 1 << endl;
//system("pause");
return 0;
}