【Swift】LeetCode 41. 缺失的第一个正数
41. 缺失的第一个正数

题目描述

思路 and Swift 题解
最开始我解决这道题目的思路是使用一个集合类型来记录数组当中出现过哪些数,由于答案出现的区间只可能在[1, n + 1],因此我们对这个区间当中的数进行遍历,找到没有出现在集合当中的那个数返回即可。
但这道题目要求只使用常数级的额外存储空间,这就意味着我们不能使用额外的数据结构,只能基于原始的数组来找到数组中缺失的第一个正数。
此时,我们要做的就是将这个数组转为一个记录数组中出现过的正数的哈希表。具体来说,首先,对于那些小于等于零的整数,我们直接对其进行一道预处理,令它们的值为n + 1,也就是最后一个可能的答案。然后,我们从头开始对数组进行遍历。我们取每次遍历到的数的绝对值(在 Swift 当中,可以直接使用全局函数abs()),如果它满足nums[i] <= n,则令var num = abs(nums[i]); nums[num - 1] = -abs(nums[num - 1])。这两行代码的含义就是将nums数组本身视为哈希表:如果nums[i]本身是正数,那么就令nums[i] - 1这个位置的值为原来的负数(注意,nums[i]在数组中可能出现过多次),标记nums[i]已经出现过了。
最后,我们从0开始遍历到n - 1,如果哪个位置的值不是负数,就说明i + 1不存在于数组当中,返回i + 1;否则说明[1, n]均出现在了数组当中,返回n + 1。
完整的 Swift 题解是:
class Solution {func firstMissingPositive(_ nums: [Int]) -> Int {var nums = Array(nums)var n = nums.countfor i in 0..<n {if nums[i] <= 0 {nums[i] = n + 1}}for i in 0..<n {var num = abs(nums[i])if num <= n {nums[num - 1] = -abs(nums[num - 1])}}for i in 0..<n {if nums[i] > 0 {return i + 1}}return n + 1}
}
