[LeetCode] 41. First Missing Positive
Given an unsorted integer array nums
, return the smallest missing positive integer.
You must implement an algorithm that runs in O(n)
time and uses constant extra space.
Example 1:
Input: nums = [1,2,0] Output: 3 Explanation: The numbers in the range [1,2] are all in the array.
Example 2:
Input: nums = [3,4,-1,1] Output: 2 Explanation: 1 is in the array but 2 is missing.
Example 3:
Input: nums = [7,8,9,11,12] Output: 1 Explanation: The smallest positive integer 1 is missing.
Constraints:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
缺失的第一个正数。
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/first-missing-positive
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
注意这道题对时间空间复杂度是有要求的,因为时间要求是 O(n) 所以没法排序;也不允许使用额外空间,所以不能用 hashmap 或者 hashset。那么这题的思路就只能是类似桶排序/抽屉原理,需要在对应的坐标上找到对应的数字,即数字 i 应该出现在坐标为 i - 1 的位置上,这样也能排除负数和大于数组长度的正数。 按照这个思路,需要扫描两遍,第一遍是将所有大于 0 且小于数组长度的正整数放到他们应该去的位置上,因为只有这些数字可以跟下标形成对应关系。第二遍再次扫描 input 的时候就能找出第一个缺失的正数了。
时间O(n) - 题目要求
空间O(1) - 题目要求
JavaScript实现
1 /** 2 * @param {number[]} nums 3 * @return {number} 4 */ 5 var firstMissingPositive = function (nums) { 6 // corner case 7 if (nums === null || nums.length === 0) return 1; 8 9 // normal case 10 for (let i = 0; i < nums.length; i++) { 11 while (nums[i] > 0 && nums[i] < nums.length && nums[nums[i] - 1] !== nums[i]) { 12 let temp = nums[nums[i] - 1]; 13 nums[nums[i] - 1] = nums[i]; 14 nums[i] = temp; 15 } 16 } 17 18 // double check 19 for (let i = 0; i < nums.length; i++) { 20 if (nums[i] !== i + 1) { 21 return i + 1; 22 } 23 } 24 return nums.length + 1; 25 };
Java实现
1 class Solution { 2 public int firstMissingPositive(int[] nums) { 3 // corner case 4 if (nums == null || nums.length == 0) { 5 return 1; 6 } 7 8 // normal case 9 for (int i = 0; i < nums.length; i++) { 10 // 如果swap的动作按照注释中的部分写 11 // 一定要把nums[nums[i] - 1]先赋值给temp,否则如下的case是会越界的 12 // [3, 4, -1, 1] 13 while (nums[i] > 0 && nums[i] < nums.length && nums[nums[i] - 1] != nums[i]) { 14 // int temp = nums[nums[i] - 1]; 15 // nums[nums[i] - 1] = nums[i]; 16 // nums[i] = temp; 17 swap(nums, i, nums[i] - 1); 18 } 19 } 20 21 // double check 22 for (int i = 0; i < nums.length; i++) { 23 if (nums[i] != i + 1) { 24 return i + 1; 25 } 26 } 27 return nums.length + 1; 28 } 29 30 private void swap(int[] nums, int i, int j) { 31 int tmp = nums[i]; 32 nums[i] = nums[j]; 33 nums[j] = tmp; 34 } 35 }
相关题目
442. Find All Duplicates in an Array