题目:缺失的第一个正数
思路1:计数排序:对0,1,2,...,n范围内的数把他放到对应的下标处。比如对于元素i放到下标i-1处,然后对数组从前往后遍历,找到第一个不匹配的,即是最小缺失正数。
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++){ //A[i] - 1 < A.length 超出范围不交换 //A[i] != A[A[i] - 1] 相等不交换 while(A[i]>0 && A[i]!=i+1 && A[i]<=n && A[i]!=A[A[i]-1]){ swap(A,i,A[i]-1); } } for(int i=0;i<n;i++){ if(A[i]!=i+1){ return i+1; } } return A[n-1]+1; } public void swap(int[] A,int i,int j){ int tmp=A[i]; A[i]=A[j]; A[j]=tmp; } }
思路2:返回得数最大不会超过数组长度加一,依次遍历。
public class Solution { public int firstMissingPositive(int[] A) { int n=A.length; for(int i=1;i<=n;i++) { int count=0; for(int j=0;j<n;j++) { if(A[j]==i) count=1; } if(count==0) return i; } return n+1; } }
思路3:先将数组排序,当排序后的数组的最后一个元素为负或为0即缺失的为1,定义一个目标min先定义为1,遍历数组,在遍历过程中将数组值与目标值比较是否相等,即min从最小正整数1开始增长
public int minNumberdisappered (int[] arr) { // write code here int len=arr.length; Arrays.sort(arr); if(len==0 || arr[len-1] <=0){ return 1; } int min=1; for(int i=0;i<len;i++){ if(arr[i]==min){ min++; } } return min; }
思路4:
- 统计出数组中的正数个数,k个
- 缺失的正整数或者是k+1,或者在1-k之间
- 要做的事情就是对于1-k之间的数字,放到它该去的位置,这个过程一定说O(n)内完成的
- 1-k之间的数都去了它对应的位置,然后遍历,第一个不应该出现的数字就是,如果0-k-1的数字都符合,那就是k+1
public static int missNum(int[] arr,int n){ if(arr.length<2 || arr==null){ return -1; } int[] help=new int[n]; for(int i=0;i<n;i++){ if(arr[i]>0 && arr[i]<=n){ help[arr[i]-1]=arr[i]; } } int temp=1; for(int i=0;i<n;i++){ if(temp!=help[i]){ break; } else{ temp++; } } return temp; }
左神:
private static int findnum(int a[]) { int l=0;//l表示已经从1到L已经出现(左边界),l的初值为0。 int r=a.length;//如果一个数字过大(不合法)扔掉,用r表示这个右边界,r初始值长度 while(l<r){ if(a[l]==l+1){//a[0]=1,0-k内合法的数有多少 l++; }else if(a[l]<=l||a[l]>r||a[l]==a[a[l]-1]){//不合法, //a[1]=3 a[a[1]-1]=a[2] a[l] = a[--r];//缩短右边界 }else{//合法但是没有在理想的位置上 swap(a,l,a[l]-1);//交换新数l和已排好的a[l]-1 } } return l+1;//返回a[l]=l+1,0-l为已出现的数,l+1代表未出现的数 } private static void swap(int[] arr, int a,int b){ int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; }