题目:
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.(Hard)
分析:
如果题目要求是O(n^2)时间复杂度,O(1)空间复杂度,或O(n)时间复杂度和O(n)空间复杂度,问题都是好解的。
前者从1开始,对每个数遍历一遍数组即可,发现没有的返回;
后者开辟一个数组flag,flag[i] == 0 或 1表示是否出现过,遍历一遍把flag填充上,再遍历一遍找到第一个没有出现过的数即可。
题目要求O(n)时间复杂度和O(1)空间复杂度,则要考虑在nums数组本身上面做文章。
考虑通过交换使得nums[i]存 i + 1,这样从头遍历找到第一个不满足的位置即可。
交换方案就是用nums[i]与 nums[nums[i] - 1]交换,直到nums[i] == i + 1或 i 超过数组范围(0...size())。
注意:加nums[i] != nums[nums[i] - 1]判断语句(见代码第6行),否则可能出现死循环。
时间复杂度,因为每次交换都会有一个元素到达正确位置,所以复杂度O(n)
代码:
1 class Solution { 2 public: 3 int firstMissingPositive(vector<int>& nums) { 4 int i = 0; 5 while (i < nums.size()) { 6 if (nums[i] > 0 && nums[i] <= nums.size() && nums[i] != i + 1 && nums[i] != nums[nums[i] - 1]) { //nums[i] != nums[nums[i] - 1] 否则类似[1,1] 7 swap(nums[i], nums[nums[i] - 1]) 8 } 9 else { 10 i++; 11 } 12 } 13 for (int j = 0; j < nums.size(); ++j) { 14 if (nums[j] != j + 1) { 15 return j + 1; 16 } 17 } 18 return nums.size() + 1; 19 } 20 };