题目描述
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
提示:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。
思路分析
思路一:先排序在寻找
如果这道题没有没有时间复杂度和空间复杂度的要求,相信大家能很轻松的写出来,比如直接对数组进行排序,然后比较得到第一个缺失的数。代码如下:
class Solution {
public int firstMissingPositive(int[] nums) {
if(null==nums||nums.length<=0){
return 1;
}
Arrays.sort(nums);
int num=1;
for(int i=0;i<nums.length;i++){
if(nums[i]==num){
num++;
}
}
return num;
}
}
以上代码也可以通过,接下来我们分析时间复杂度和空间复杂度。
时间复杂度: 因为这里用到了JDK提供的Arrays.sort(int[] nums)进行排序,JDK1.8是这样描述的
排序算法是由Vladimir Yaroslavskiy,Jon Bentley和Joshua Bloch提供的双轴快速排序。 该算法在许多数据集上提供O(n log(n))性能,导致其他快速排序降级为二次性能,并且通常比传统(单轴)Quicksort实现更快。
因此该题目的时间复杂度为 O(nlog(n)).
空间复杂度: 这里并没有额外的创建数组,因此空间复杂度为O(1)。
可以得出结论,空间复杂度符合题目要求,时间复杂度不符合题目的要求!!
思路二:将数组索引作为哈希表
在使用该思路求解这道题目之前,我们可以先看一道简单题
268. 缺失数字
题目描述:
给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1]
输出: 2
示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
这道题目相对来说比较简单,数字序列是从0到n,因此我们只需要将每个数字放置它对应的下标处,然后遍历,如果 i != nums[i] 则返回结果。代码如下:
class Solution {
public int missingNumber(int[] nums) {
if(nums==null||nums.length<=0){
return 0;
}
int len=nums.length;
for(int i=0;i<len;i++){
while(nums[i]>=0&&nums[i]<len&&nums[i]!=i){
//将下标i处的值nums[i]放到下标为nums[i]处
swap(nums,i,nums[i]);
}
}
for(int i=0;i<len;i++){
if(nums[i]!=i){
return i;
}
}
return len;
}
public void swap(int[] nums,int i,int j){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
现在我们回到这道题目,确实的第一个整数,与268题缺失数字的不同之处在于数字序列中有了负数,同时从1开始计数而不是从0。即下标 i 处存放的的值应为i+1,也即num[i]应该存放在下标 nums[i]-1处。
class Solution {
public int firstMissingPositive(int[] nums) {
if(nums==null||nums.length<0){
return 1;
}
int len=nums.length;
for(int i=0;i<len;i++){
//0 1 2-> 1 2 0
while(nums[i]>0&&nums[i]<=len&&nums[i]!=nums[nums[i]-1]){
//将下标i处的值应该存放的数值为 i+1
//也即num[i]存放在下标nums[i]-1处
swap(nums,i,nums[i]-1);
}
}
for(int i=0;i<len;i++){
if(nums[i]!=i+1){
return i+1;
}
}
return len+1;
}
public void swap(int[] nums,int i,int j){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
时间复杂度: 两次for循环解决问题,因此时间复杂度为n。
空间复杂度: 并没有额外的开辟数组空间,因此空间复杂度为O(1).
符合题目的要求!!!