题解一:Hash+遍历(不符合题目要求)
主要思路:
根据题意n的范围是,建立hash表
①对数字散列到hash表,非正整数忽略
②对hash表进行从小到大的遍历,对应key值没有value的bucket即为第一个未出现的最小正整数
图示
复杂度分析:
时间复杂度分析:,散列的时间为O(N),而遍历时间复杂度也为O(N),综上时间复杂度为O(N)
空间复杂度分析:,开辟了一个最大的为N的hash表
实现如下:
int hash_table[1000000000];//hash表,放在外面定义的原因是,可能超过了栈空间
class Solution {
public:
/**
* return the min number
* @param arr int整型vector the array
* @return int整型
*/
int minNumberdisappered(vector<int>& arr) {
// write code here
for(auto i:arr){
if(i<0)continue;//负数不用关心
else hash_table[i]=i;//散列
}
for(int i=1;i<1000000000;i++){
if(hash_table[i]!=i) return i;//找未出现的最小正整数
}
return 0;
}
};题解二:原地交换
主要思路:根据题目要求,时间复杂度为O(N),空间复杂度为O(1),那么只能在原地采用交换策略的算法处理本算法题
①未出现的最小正整数一定是从1开始的,我们的的数组大小为n,那么对于大于n的与小于等于0的数我们可以抛弃掉;
②将大于0与小于等于n的数字与数组下标为n-1的数据交换
③遍历数组找到下标n与数字为n+1不匹配的第一个数,找不到则代表全部缺失的是第n+1个数
图示:
复杂度分析:
时间复杂度分析:,通过一轮遍历都能将数字交换到对应的下标处,因为while循环未来把数字与对应的下标对应上,不会对假设对整个数组遍历了,那么数字都会对应到正确的位置,后续不会跳入while循环执行
空间复杂度分析:,原地交换
实现如下:
class Solution {
public:
/**
* return the min number
* @param arr int整型vector the array
* @return int整型
*/
int minNumberdisappered(vector<int>& arr) {
// write code here
if(arr.size()==0)return 0;//特判
int n=arr.size();
for(int i=0;i<n;++i){
while(arr[i]!=i+1){////数字n与下标n-1不对应,需要交换;
if(arr[i]<=0||arr[i]>n||arr[i]==arr[arr[i]-1])//arr[i]是非正整数,或者大于n,或者已经与下标正确对应
break;
//交换,将arr[i]放到arr[i]-1的下标位置
int index=arr[i]-1;
arr[i]=arr[index];
arr[index]=index+1;
}
}
for(int i=0;i<n;++i){//找未出现的最小正整数
if(arr[i]!=i+1)
return i+1;
}
return n+1;//下标与数字都对应,返回n+1;
}
};
京公网安备 11010502036488号