LeetCode缺失的第一个正数

41. 缺失的第一个正数

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1

输入:nums = [1,2,0]

输出:3

示例 2

输入:nums = [3,4,-1,1]

输出:2

示例 3

输入:nums = [7,8,9,11,12]

输出:1

思路:

       题目中要我们找最小正整数,也就是要从1开始找,最容易想到的思路就是从i=1开始遍历;不断判断当前数是否在数组中,即判断if i in nums。但是这种思路的时间复杂度是O(n方),因为遍历就有n的复杂度,判断每一个值是否在数组中又是n的复杂度,所以总体是O(n方)复杂度。

       如何才能在时间复杂度只有O(n)的情况下完成呢?题目中要求只能使用常数级别的额外空间,其实就提示了我们可以先本地修改数组。那怎样怎样修改可以方便我们从1开始判断呢?按值归位法——将数组的每一个元素移动到以它的值为位置的地方。比如我们将数组中的1移动到下标为0也就是第一个位置;数组中的2移动到下表为1也就是第二个位置……若数组的值超出了数组长度没法安放,我们就忽略这个值。

       当我们按上面这种策略修改好了给定数组后,我们再来进行结果的查找。我们要搜索1,只需要检查第1个位置是不是1,搜索2则检查第2个位置是不是2……一旦我们发现位置与值不一致,那么这个位置就是没有出现的最小正整数了。若数组中所有的值都可以到正确的位置上,那没出现的最小的正数就是数组最大值的下一个值了。      

       下面写出实现代码,要注意因为我们数组的下标是从0开始的,所以在代码实现上要注意。

代码:

class Solution(object):

    def firstMissingPositive(self, arr):

        if not arr:return 1#数组为空,第一个未出现的正整数是1

        lenth=len(arr)#拿到长度lenth

        for i in range(lenth):

            #注意,数字1就放在arr[0]上,而不是arr[1]

            #用while而非if 这样可以一直交换不在正确位置上的arr[i]

            #当这个值可以被正确归位(在1-lenth之间)且这个值“不在其位”

            while arr[i]>=1 and arr[i]<=lenth and arr[i]!=arr[arr[i]-1]: 

                #将下标arr[i]-1与下标i的值交换

                arr[arr[i]-1],arr[i] = arr[i], arr[arr[i]-1]

        #放好后从前往后遍历即可,遇到位置和数值不一致的就返回下标值

        for i,a in enumerate(arr):

            if i+1!=a:

                return i+1

        #如果到最后都没返回,证明是从1开始的有序,要返回外边第n+1个数

        return lenth+1

小结:

       “按值归位”法在很多类似的数组题目中都有应用,所以像上面这种用while循环来交换的操作是非常常用的,只要用“按值归位”,基本就是一个固定操作。

       这里面比较难理解的就是为什么用while,而不是if,因为我们有可能不止交换一次。比如我们把当前值送入它正确的位置后,arr[i]变成了新的值,这个值也不一定是正好“在其位”的,所以可能要再次它的正确位置并作交换。所以整个while的作用就是确保:假如arr[i]的值可以被正确归位(在1-lenth之间)且“不在其位”,就把它送过去。

       再小小强调思考一下为什么通过这样的方法就可以实现复杂度为O(n)的搜索呢?如果我们按最普通的方法从1开始遍历和查找,这样我们的额外的查找复杂度必然是O(n);但如果提前进行了归位,那么我们只需要遍历一次数组,遍历的同时是去“检查”1而不是去“查找”1,自然就不需要额外查找的时间复杂度了。

posted @   JunanP  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示