From 223aee627ec6c0c4c33bafe16b7aaf9349b2618b Mon Sep 17 00:00:00 2001 From: gameloader Date: Tue, 26 Mar 2024 16:24:40 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 59d55f1..7ae78fd 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -2044,3 +2044,73 @@ func findDuplicates(nums []int) []int { return result } ``` + +## day28 2024-03-26 + +### 41. First Missing Positive + +Given an unsorted integer array nums. Return the smallest positive integer that is not present in nums. + +You must implement an algorithm that runs in O(n) time and uses O(1) auxiliary space. + +![0326ratU6vVn9qLn](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0326ratU6vVn9qLn.png) + +### 题解 + +本题要求O(n)的时间复杂度和O(1)的空间复杂度, 解题思路上与昨天的题目相似, 考虑到数组长度为n, 即使是从1开始的连续正整数, 最大填充到n. 故用数组中的数作为下标修改对应位置的值来标记某个数是否存在是可行的. 但要注意, 当前数组中可能出负数和超过n的数字, 如果想使用将数作为下标将对应位置数设为负数的方式来提供信息, 则要先对负数和超过n的数字进行处理, 为了区分被标记的数和本身为负的数, 将负数和超过n的数修改为0. 再遍历数组按照昨天的思路将数作为下标, 将相应位置数设为负数标记已经访问. 这里可以将数全部设为-1. 最后再遍历一遍数组, 找到第一个数字大于等于0的数的下标, 即为丢失的最小正整数. 这样需要固定遍历三遍数组, 且空间复杂度为O(1). + +### 代码 + +```go +func firstMissingPositive(nums []int) int { + for index, value := range nums { + if value < 0 || value > len(nums) { + nums[index] = 0 + } + } + flag := 0 + for _, value := range nums { + if abs(value) > 1 || value == -1{ + if nums[abs(value)-1] == 1 { + flag = 1 + nums[abs(value)-1] = -1 + } else if nums[abs(value)-1] == 0 { + nums[abs(value)-1] = -1 + } else if nums[abs(value)-1] > 1 { + nums[abs(value)-1] = -nums[abs(value)-1] + } + }else if value == 1{ + flag = 1 + if nums[0] == 0{ + nums[0] = -1 + }else if nums[0] > 1{ + nums[0] = -nums[0] + } + } + } + for index, value := range nums { + if flag == 1 && index == 0 { + continue + } else if index == 0 && flag == 0 { + return 1 + } + if value >= 0 { + return index + 1 + } + } + return len(nums)+1 +} + +func abs(num int) int { + if num < 0 { + return -num + } else { + return num + } +} + +``` + +### 总结 + +查看最快速代码, 其将负数直接修改为整数类型最大值, 对于超过数组长度的数直接忽略, 不作处理, 其余的当作下标取对应位置的相反数. 这样处理起来思路比较清晰.