zoukankan      html  css  js  c++  java
  • First Missing Positive

    Date:

      Nov. 1, 2017

    Problem:

      https://leetcode.com/problems/first-missing-positive/description/

    Description:

      Given an unsorted integer array, find the first missing positive integer.

      For example,

    Give [1, 2, 0], return 3
    Give [3, 4, -1, 1] return 2

      Your algorithm should run in O(n) time and uses constant space.

      

      emmmmmm。

      我有一个大胆的想法。

    1 class Solution:
    2     def firstMissingPositive(self, nums):
    3         pst = list(range(2333333))
    4         for i in nums:
    5             if i > 0:
    6                 pst[i] = 0
    7         for i in pst:
    8             if i > 0:
    9                 return i

      本地测试,代码运行时间在200~300ms间。

      提交,TLE。

      一看数据,[1, 1, 1, 1, 1],不对劲呀。本地一跑,300ms,没问题。再提交,TLE。

      认真看了看数据,发现前面已经过了一半测试点,不可能在这地方栽了。目测是反复运行同一函数累计时间超时了(和codewars一个尿性)。

    1 class Solution:
    2     def firstMissingPositive(self, nums):
    3         pst = list(range(23333))
    4         for i in nums:
    5             if i > 0:
    6                 pst[i] = 0
    7         for i in pst:
    8             if i > 0:
    9                 return i

      提交,AC。

      ……

      2333333。

      正经的解法。

      中心思想其实和计数排序有点像:把数放到它们该去的地方。

      考虑一个长度为k的输入,它最多无死角覆盖1~k这些正整数,如果有大于k的数,1~k中显然会出现我们要找的missing positive。所以我们要做的事情就是将nums[1]~nums[k]放回它们该待的地方——如果放得进去的话(它们必须不能是负数或者超过k的数)。而当它们确实都覆盖了1~k时,我们要找的数就是k+1。

      另一个更好理解的角度,k+1个抽屉,k个苹果,容斥原理。

      所以我们令i=0~(k-1),检查每一个nums[i],当nums[i]在1到k之间(有位可放),nums[i] != nums[nums[i]-1](还没放入)时,我们就将nums[i]与nums[nums[i]-1]交换,将正确的数放入,不正确的数取出,不断重复此操作,直到发现nums[i]是无位可放的为止。

      在操作过一遍之后,我们再度检查nums[i],返回第一个nums[i] != i+1(不正确)的数i+1。如果没有检查到,就返回k+1。

      这个算法的复杂度为O(N)。

      以下是submission。

     1 class Solution:
     2     def firstMissingPositive(self, nums):
     3         k = len(nums)
     4         for i in range(k):
     5             while 0 < nums[i] <= k and nums[i] != nums[nums[i] - 1]:
     6                 nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
     7         for i in range(k):
     8             if nums[i] != i + 1:
     9                 return i + 1
    10         return k + 1
  • 相关阅读:
    ORACLE日期时间函数大全
    orcal基础
    javaweb学习总结——基于Servlet+JSP+JavaBean开发模式的用户登录注册
    一个DataTable赋值给另一个DataTable的常用方法
    ios开发 解释器和编译器
    ios面试题(五)-多线程
    ios面试题(四)-block
    ios面试题(三)
    ios开发面试题(二)
    ios开发面试题(一)
  • 原文地址:https://www.cnblogs.com/neopolitan/p/7768395.html
Copyright © 2011-2022 走看看