题目大意:

  传入整数数组nums,求nums中未出现的正整数中的最小值。要求算法在O(n)时间复杂度内实现,并且只能分配常量空间。


分析:

  一般碰到这种问题,都先对数组进行排序,再遍历数组就可以找到最小的在nums中没有出现过的正整数。但是由于排序的时间复杂度一般为O(nlog2(n)),因此时间复杂度没有达到要求。

  之后再转回排序的方式,有一种排序的方式称为桶排序,只要有足够的空间,就可以在O(n)的时间复杂度内完成排序过程。但事实是只能分配常量空间。

  只能分配常量空间还要求时间复杂度为O(n),这时候我们就只能打起传入的参数nums的主意,能不能用nums来存储我们的中间结果呢?

  我们要做的就是遍历nums,将每个在nums中出现的正整数t写入到nums[t-1]中。在完成了这个过程后,再遍历数组,直到找到一个下标i,使得nums[i]不等于i+1,显然i+1就是nums缺失的最小正整数。

  下面给出伪代码:

  for(i = 0; i < nums.length; i++)

    num = nums[i]

    rightPos = num - 1

    while(rightPos >= 0 && rightPos < nums.length && nums[rightPos] != num)

      temp = num[rightPos]

      num[rightPos] = num

      num = temp

      rightPos = num - 1

  上面就是第一阶段的代码,负责将每个在nums中出现的正整数t写入到nums[t-1]中。而当然对于一些负数和过大的正整数(大于n),由于无处可写就会直接被跳过,而这些整数也必然不会包含我们所要求的结果。

  再说明一下为什么这段代码能在O(n)时间复杂度内完成。我们称一个下标i为正确的,当且仅当nums[i] = i + 1,而不正确的下标则称为错误的,显然在上面的代码逻辑中一旦一个下标i是正确的,那么就不会有值写入到nums[i]中(nums[rightPos] != num条件保证),即一个正确的下标不会转变为错误的下标。在不考虑内部while循环占用的时间的情况下,for循环总共的时间复杂度为O(n)毋庸质疑。而每次调用while循环,都会将一个错误值纠正为正确的值,而最多只会存在n个正确值,这就意味着while循环总共只会执行n次,而一次while循环内部的动作所耗费的时间复杂度为O(1),故总的时间复杂度就为"for循环不考虑while的时间复杂度"+"for循环内while的时间复杂度"=O(n)+O(n)=O(n)。

  而上面这个过程只额外分配了固定的变量数目,因此空间复杂度为O(1)。由于递归也要占用栈空间,即空间复杂度会增加,但这里用while而非递归,因此空间复杂度不会被破坏。


  给出Java的解决代码:

 public class Solution {
     public int firstMissingPositive(int[] nums) {
         if(nums.length == 0)
         {
             return 1;
         }
         for(int i = 0, bound = nums.length; i < bound; i++)
         {
             int num = nums[i];
             int rightPos = num - 1;
             while(rightPos >= 0 && rightPos < bound && nums[rightPos] != num)
             {
                 int tmp = nums[rightPos];
                 nums[rightPos] = num;
                 num = tmp;
                 rightPos = num - 1;
             }
         }
         for(int i = 0, bound = nums.length; i < bound; i++)
         {
             if(nums[i] != i + 1)
             {
                 return i + 1;
             }
         }
         return nums.length + 1;
     }
 }

leetcode:First Missing Positive分析和实现的更多相关文章

  1. [LeetCode] First Missing Positive 首个缺失的正数

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...

  2. Leetcode First Missing Positive

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...

  3. LeetCode: First Missing Positive 解题报告

    First Missing Positive Given an unsorted integer array, find the first missing positive integer. For ...

  4. LeetCode – First Missing Positive

    Given an unsorted integer array, find the smallest missing positive integer. Example 1: Input: [1,2, ...

  5. LeetCode OJ-- First Missing Positive

    https://oj.leetcode.com/problems/first-missing-positive/ 给一列数,找出缺失的第一个正数.要求时间复杂度 O(n) 第一步遍历一遍,找出最大的数 ...

  6. leetcode First Missing Positive hashset简单应用

    public class Solution { public int firstMissingPositive(int[] A) { HashSet<Integer> hash=new H ...

  7. leetcode First Missing Positive python

    class Solution(object): def firstMissingPositive(self, nums): """ :type nums: List[in ...

  8. 【LeetCode题意分析&解答】41. First Missing Positive

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...

  9. [LeetCode]题解(python):041-First Missing Positive

    题目来源 https://leetcode.com/problems/first-missing-positive/ Given an unsorted integer array, find the ...

随机推荐

  1. PHP防止mysql注入方法

    本文纲要: 1. 初始化你的变量 2. 一定记得要过滤你的变量 [一.在服务器端配置] 安全,PHP代码编写是一方面,PHP的配置更是非常关键. 我们php手手工安装的,php的默认配置文件在 /us ...

  2. GitLab non-standard SSH port

    /***************************************************************************** * GitLab non-standard ...

  3. InnoDB MVCC RR隔离级别下的数据可见性总结

    一.背景 熟悉数据库隔离级别的人都知道,在RR(可重复读)隔离级别下,无论何时多次执行相同的SELECT快照读语句,得到的结果集都是完全一样的,即便两次SELECT语句执行期间,其他事务已经改变了该查 ...

  4. [转]Socket编程中,阻塞与非阻塞的区别

    阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket.如果在队列中没有请示将会出现什么情况呢?那个方法将会等待一个的到 ...

  5. python 使用sk_learn 遇到 问题ValueError: Expected 2D array, got 1D array instead:

    这里我找到我的问题是: 使用的是一个新的scikit学习版本,它抛出了一个错误,因为在新版本中,所有东西都必须是一个二维矩阵,甚至是一个列或行. 它甚至说:用数组来重塑你的数据.如果您的数据有一个单独 ...

  6. request.getDispatcher().forward(request,response)和response.sendRedirect()的区别

    在进行web开发时,跳转是最常见的,今天在这里来学习下2种跳转: 第一种是request.getDispatcher().forward(request,response): 1.属于转发,也是服务器 ...

  7. HTML中id与name的用法

    可以说几乎每个做过Web开发的人都问过,到底元素的ID和Name有什么区别阿?为什么有了ID还要有Name呢? 而同样我们也可以得到最经典的答案:ID就像是一个人的身份证号码,而Name就像是他的名字 ...

  8. python的正则re模块

    一. python的正则 python的正则模块re,是其内置模块,可以直接导入,即import re.python的正则和其他应用的正则及其相似,有其他基础的话,学起来还是比较简单的. 二. 正则前 ...

  9. jQuery火箭图标返回顶部代码

    在网上找来段使用jQuery火箭图标返回顶部代码,感觉比较酷,比较炫,大概样式如下, 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...

  10. android jUnit test 进行自动化测试

    一. 被test的工程: 新建一个android工程:D_session:它有一个activity:D_sessionActivity:package名:com.mysession 二.测试工程: 新 ...