1. 程式人生 > >leetcode41_缺失的第一個正數

leetcode41_缺失的第一個正數

給定一個未排序的整數陣列,找出其中沒有出現的最小的正整數。

示例 1:

輸入: [1,2,0]
輸出: 3
示例 2:

輸入: [3,4,-1,1]
輸出: 2
示例 3:

輸入: [7,8,9,11,12]
輸出: 1
說明:

你的演算法的時間複雜度應為O(n),並且只能使用常數級別的空間。
 */

/*
 * 題目大意:找到一個未排序序列中的第一個缺失的正數。簡而言之,就是看1在不在這個序列中,如果不在的話輸出1;
 * 否則看2在不在這個序列中,如果不在的話輸出2;否則看3在不在這個序列中

思路:

本題的一個難點就在 要求O(n)時間複雜度  O(1)空間複雜度  不允許申請新的空間

1.先說說O(n)空間複雜度的解法   利用HashSet存放所有的陣列元素   然後從1開始  找到第一個不在set裡面的元素 就是最小值

 

2.O(1)空間複雜度的解法

nums[i]代表該數在陣列中應該處於第i個位置  對應陣列的索引就是i-1  也就是nums[i]-1

舉個例子,假設有序列[4,2,6,1,-3],首先看第一個數4,它正確的位置應該是在序列的第4個位置(位置數從1開始,正確的位置是第一個位置放1,第二個位置放2,第三個位置放3……最後我們只要看哪個位置放的不是理想的數,
那麼它就是第一個缺失的正數)。我們將4與第4個位置上的“1”進行交換,序列變成[1,2,6,4,-3];接著我們還是
看第一個數,現在變成了“1”,它的確在它正確的位置,好了,我們再看第二個數2,也在正確的位置。第三個數6,
本來應該放在第6個位置,可是該序列總共就5個位置,所以不移動;第四個數4在它的正確位置,不動;第五個數是負數,
不動。最後,從前往後看,發現在第三個位置本該出現的3沒有出現,所有該序列缺失的第一個正數是3。

     //時間複雜度應為O(n),並且只能使用常數級別的空間
	 public static int firstMissingPositive(int[] nums) {
		
		 int len=nums.length;
		 for (int i = 0; i < len; i++) {
			 //nums[i]代表該數在陣列中應該處於第i個位置  對應陣列的索引就是i-1  也就是nums[i]-1
			 //由於負數不考慮  所以nums[i]>0  而nums[i]如果大於陣列長度 則也不用交換  
			while (nums[i]>0&&nums[i]<=len&&nums[i]!=nums[nums[i]-1]) {
				swap(nums,i,nums[i]-1);
			}
		}
		 //操作完成之後 遍歷 找到nums[i]第一個不等於i+1的點  結果就是i+1
		 for (int i = 0; i < len; i++) {
			if (nums[i]!=i+1) {
				return i+1;
			}
		}
		 //都符合要求了  說明陣列的值是 1~nums.length  則返回		 
		 return len+1;        
	    }

	private static void swap(int[] nums, int i, int j) {
		int temp=nums[i];
		nums[i]=nums[j];
		nums[j]=temp;
	}