描述
给定一个无重复元素的整数数组nums,请你找出其中没有出现的最小的正整数
进阶: 空间复杂度 O(1),时间复杂度 O(n)
数据范围:
-2^31<=nums[i]<=2^31-1
0<=len(nums)<=5*10^5
示例1
输入:
[1,0,2]
复制返回值:
3
复制
示例2
输入:
[-2,3,4,1,5]
复制返回值:
2
复制
示例3
输入:
[4,5,6,8,9]
复制返回值:
1
解题报告:
注意这题的关键信息,每个数字都各不相同,且len(nums)<=5*10^5
要求空间复杂度O(1)所以可以考虑复用原数组的空间。
首先从答案出发,考虑答案的可能范围,发现一定在[1,n+1],把不合法的值都归一化成-1。
然后因为各不相同,所以我们可以把每个不在对应位置上的都给他变到对应位置上。这个对应位置,可以约定为,x在nums[x-1]上,这样就可以保证[1,n]会在[0,n-1]位置上。
然后从小到大遍历,如果nums[i] != i+1,则 i 就是答案。
AC代码:
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param nums int整型vector * @return int整型*/int minNumberDisappeared(vector<int>& nums) {// write code herefor(int i = 0; i<nums.size(); i++) {if(nums[i] <= 0 || nums[i] > int(nums.size())) nums[i] = -1;}for(int i = 0; i<nums.size(); i++) {if(nums[i] == -1) continue;int p = nums[i];while(p>0 && nums[p-1] != p) {int cur_num = nums[p-1];nums[p-1] = p;p = cur_num;}}for(int i = 0; i<nums.size(); i++) {if(nums[i] != i+1) return i+1;}return nums.size()+1;}
};
/*
从结果入手考虑,结果肯定在(1,len)之间*/