1. 程式人生 > >【leetcode】41.(Hard)First Missing Positive

【leetcode】41.(Hard)First Missing Positive

題目連結

解題思路: 歸併排序——剔重——找到最小非負數——折半查詢 這道題就是需要考慮的邊界比較多 另外就是對重複數字的處理

提交程式碼:

class Solution {
    public int firstMissingPositive(int[] nums) {
    	if(nums.length==0)		return 1;
    	if(nums.length==1)
    		return (nums[0]<=0||nums[0]>=2)?1:2;
    	
    	//排序
        mergeSort(nums,0,nums.length-1);
      //剔重
int i=1,j=1,flagnum=nums[0]; while(i<nums.length) { while(i<nums.length&&nums[i]==flagnum) i++; if(i<nums.length) { nums[j++]=nums[i]; flagnum=nums[i++]; } } int len=j; //邊界 if
(nums[len-1]<=0||nums[0]>=2) return 1; if((nums[len-1]-nums[0])==(len-1)) return nums[len-1]+1; //找到第一個0及以上的數 int mid,left=0,right=len; int posmin=0; while(left<=right) { if(nums[left]>0) { posmin=left; break
; } posmin=(left+right)/2; if(nums[posmin]>0) right=posmin; else if(nums[posmin]==0) break; else left=posmin+1; } if(nums[posmin]>=2) return 1; //此時nums[left]是0 或者1 left=posmin;right=len-1; while(left<right) { if(left==(right-1)) return nums[left]+1; //134567 mid=(left+right)/2; if((mid-left)!=(nums[mid]-nums[left])) right=mid; else if((right-mid)!=(nums[right]-nums[mid])) left=mid; else { if((nums[mid+1]-nums[mid])!=1) return nums[mid]+1; else return nums[right]+1; } } if(nums[left]==1) return 2; else return nums[right]-1; } public void mergeSort(int[] nums,int left,int right){ if(left>=right) return; int mid=(left+right)/2; mergeSort(nums,left,mid); mergeSort(nums,mid+1,right); merge(nums,left,mid,right); } public void merge(int[] nums,int left,int mid,int right) { if(left==right) return; int len=right-left+1; int tmp[]=new int[len]; int i=left,j=mid+1,k=0; while(i<=mid&&j<=right) tmp[k++]=nums[i]<nums[j]?nums[i++]:nums[j++]; while(i<=mid) tmp[k++]=nums[i++]; while(j<=right) tmp[k++]=nums[j++]; for(k=0;k<len;k++) nums[left++]=tmp[k]; } }

執行結果: 在這裡插入圖片描述