Given an unsorted integer array, find the smallest missing positive integer.
Example 1:
Input: [1,2,0] Output: 3
Example 2:
Input: [3,4,-1,1] Output: 2
Example 3:
Input: [7,8,9,11,12] Output: 1
Note:
Your algorithm should run in O(n) time and uses constant extra space.
1. 如果不限制使用额外空间的话,可以用hashset存储所有的数,然后找出最大值。再遍历一次,如果i(从1开始)不在set里就返回它,全在就返回max+1.
class Solution { public int firstMissingPositive(int[] nums) { Set<Integer> set = new HashSet<Integer>(); int max = 0; for(int i = 0; i < nums.length; i++){ if(nums[i] < 0) continue; //记得跳过负数 set.add(nums[i]); max = Math.max(max, nums[i]); } for(int i = 0; i <= nums.length; ++i){ if(!set.contains(i+1)) {return i+1;} } return max + 1; } }
2.但是题目规定了不能使用额外空间,那么就采取交换的策略,强行将index与elements联系起来。
比如,1 就应该在nums[0], 2就应该在nums[3],以此类推,nums[ i ] == nums[ nums[ i ] - 1]。
交换结束后,重新遍历一次数组,返回第一个不满足条件的即可。
class Solution { public int firstMissingPositive(int[] nums) { // Set<Integer> set = new HashSet<Integer>(); // int max = 0; // for(int i = 0; i < nums.length; i++){ // if(nums[i] < 0) continue; // set.add(nums[i]); // max = Math.max(max, nums[i]); // } // for(int i = 0; i <= nums.length; ++i){ // if(!set.contains(i+1)) // {return i+1;} // } // return max + 1; for(int i = 0; i < nums.length; i++){ while(nums[i] > 0 && nums[i] <= nums.length && nums[i] != nums[nums[i] - 1]){// 必须先判断完nums[ i ] 的边界条件,否则会runtime error,原因是假如nums[ 1 ] == 8, 然而我们的数组只有5个元素,根本就不存在nums[ 8 - 1] swap(nums, i, nums[i] - 1); } } for(int i = 0; i < nums.length; i++){ if(nums[i] != i+1 ) return i + 1; } return nums.length + 1; } public void swap(int[] n, int i, int j){ int temp = n[i]; n[i] = n[j]; n[j] = temp; } }
为什么上面是while而不是if?因为if只会判断一次,swap一次,不会把数字放到正确的位置,while会一直swap错误的数字,在保证正确的数字在正确的位置情况下,错误的数不会再正确的位置。