Given an unsorted integer array, find the first missing positive integer.
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
给定未排序的数字序列,找出最小的未出现的正数;0不算正数,O(n)时间完成,不能额外空间。
说到未排序,首先想到排序~ 排序好后从头到尾检查,能够完成解答,但是所有比较排序至少O(nlgn);桶排序,计数排序啥的的确O(n),可是需要额外的空间。看来此路不通。
考虑了下需要的变量:数组的总数(这样最大的n就可以知道,有),数组元素(有),从1-n每次要比较的自然数(可以有,但是没办法一直存储,或者说每次都要从头到尾扫一遍数组),看来问题出在这里。山重水复疑无路之时,想到数组本身的下标就是一个很好的记录点。好!
对应的数放到对应的索引上,例如1放到A[1]上,这样只需要O(n)的遍历就能完成,然后用一个O(n)的遍历找第一个没有放到索引上的数返回。
<span style="font-family:Times New Roman;color:#333333;">public class Solution {
public int firstMissingPositive(int[] A) {
if(A==null){
return 1;
}
if(A.length == 0){
return 1;
}
int n = A.length;
for(int i =0;i<n;i++){
if(A[i]>=0&&A[i]<n&&A[A[i]]!=A[i]){
int temp =A[i];
A[i]=A[A[i]];
A[temp]=temp;
i--;
}
}
for(int i=1;i<n;i++){
if(A[i]!=i){
return i;
}
}
return A[0]==n?n+1:n;
}
}</span>
细节
public class Solution {
public int firstMissingPositive(int[] A) {
if(A == null || A.length ==0){
return 1;
}
int n = A.length;
for(int i =0;i<n;i++){
int cur = A[i];
if( cur <1 || cur > n || A[cur-1]==cur ){
continue;
}
else{
int temp =cur;
A[i]= A[cur-1];
A[cur-1]=temp;
i--;
}
}
for(int i=0;i<n;i++){
if(A[i]!=i+1){
return i+1;
}
}
return n+1;
}
}
循环内判断continue的情形很容易出错。1 顺序,先要判断交换的点在1-n 2 需要判断交换的点的值和自己是不同的,不然会循环交换。