【leetcode】41. First Missing Positive

题目如下:

解题思路:这题看起来和【leetcode】448. Find All Numbers Disappeared in an Array很相似,但是有几点不同:一是本题的输入存在负数,二是没有约定输入元素的最大值。那么,怎么可以把本题转换成448题的场景呢?首先,我们可以求出输入数组nums中所有正整数的数量,记为p,那么显然能得出这个结论:1 <=answer < p+1。然后,我们可以通过交换把所有值不在这个区间内的元素值移动到数组的后半部分。记nums前半部分[0:length]为符合answer取值区间的元素,既然已经得到了这个区间,那么就可以模仿448题的方法再次交换,使得元素的值和下标匹配。

代码如下:

class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        positiveCount = 0
        minv = float('inf')
        for i in nums:
            if i <= 0:
                continue
            minv = min(minv,i)
            positiveCount += 1
        if minv < 1:
            return 1
        endInx = len(nums)-1
        for i in xrange(len(nums)):
            if nums[i] <= 0 or nums[i] > positiveCount:
                for j in xrange(endInx,i,-1):
                    if nums[j] > 0 and nums[j] <= positiveCount:
                        t = nums[i]
                        nums[i] = nums[j]
                        nums[j] = t
                        endInx = j
                        break
        # nums subarray is nums[:endInx] 
        length = len(nums)
        for i in xrange(len(nums)):
            if nums[i] > positiveCount or nums[i] < 0:
                length = i
                break
        #nums[:length]  这个子集保存的是所有符合answer的元素
        i = 0
        while i < length:
            if nums[i] >= length:
                i += 1
                pass
            elif nums[i]-1 != i and nums[nums[i]-1] != nums[i]: # 记 nums = [1,1,2] ,第二个1是否要移动到下标为0的位置,要判断下标为0的元素是否已经和下标匹配
                src = nums[i]
                dest = nums[nums[i]-1]
                nums[nums[i]-1] = src
                nums[i] = dest
            else:
                i += 1

        #print nums[:length]
        for i in xrange(length):
            if i+1 != nums[i]:
                return i+1
        return length+1

 

posted @ 2018-07-13 11:03  seyjs  阅读(155)  评论(0编辑  收藏  举报