zoukankan      html  css  js  c++  java
  • [leetcode] First Missing Positive

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

    Example 1:

    Input: [1,2,0]
    Output: 3
    

    Example 2:

    Input: [3,4,-1,1]
    Output: 2
    

    Example 3:

    Input: [7,8,9,11,12]
    Output: 1
    

    Note:

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


    分析:题目意思很明确,要求找数组中没有出现的最小的正整数。

    一个最原始的思路,就是从1开始递增,挨个判断是否在数组中。因此需要用一个list保存一下原数组元素,才能用contains方法。

     1 class Solution {
     2     public int firstMissingPositive(int[] nums) {
     3         List<Integer> list = new ArrayList<>();
     4         for ( int n:nums )  
     5             list.add(n);
     6         for ( int i = 1 ; ; i ++ ){
     7             if (!list.contains(i) ) return i;
     8         }
     9     }
    10 }

        运行时间7ms,但是这种方法,时间复杂度是O(n),空间复杂度是O(n)。不符合要求。

    第二个思路:参考了网上大神的代码,毕竟是hard,求解太巧妙了。

    这道题要求用线性时间和常量空间,思想借鉴到了Counting sort中的方法,参见Counting sort - Wikipedia。既然不能用额外空间,那就只有利用数组本身,跟Counting sort一样,利用数组的index来作为数字本身的索引,把正数按照递增顺序依次放到数组中。即让A[0]=1, A[1]=2, A[2]=3, ... , 这样一来,最后如果哪个数组元素违反了A[i]=i+1即说明i+1就是我们要求的第一个缺失的正数。对于那些不在范围内的数字,我们可以直接跳过,比如说负数,0,或者超过数组长度的正数,这些都不会是我们的答案。

    代码如下:

     1 class Solution {
     2     public int firstMissingPositive(int[] nums) {
     3         //把所有数字放回对应的index;
     4         int start = 0;
     5         while(start < nums.length) {
     6             if(nums[start] <= 0 || nums[start] == start + 1 || nums[start] > nums.length) {
     7                 start++;
     8             } else if(nums[nums[start] - 1] != nums[start]){
     9                 swap(nums, start, nums[start] - 1);
    10             } else {
    11                 start++;
    12             }
    13         }
    14         start = 0;
    15         while(start < nums.length) {
    16             if(nums[start] == start + 1) {
    17                 start++;
    18             } else {
    19                 break;
    20             }
    21         }
    22         return start + 1;
    23     }
    24     private void swap(int[] nums, int l, int r) {
    25         int tmp = nums[l];
    26         nums[l] = nums[r];
    27         nums[r] = tmp;
    28     }
    29 } 
  • 相关阅读:
    阿里巴巴JAVA开发手册
    2018开源中国最受欢迎的中国软件
    Java并发编程(多线程)中的相关概念
    关于HashMap自定义key重写hashCode和equals的问题
    MySQL视图 索引 存储过程 触发器 函数
    MySql/Oracle树形结构查询
    码农也来关注下经济问题<美元加息>对我们的影响
    不懂技术却能做到月入20万美元,差距在哪里
    solidity智能合约如何判断mapping值为空
    微信很好用却很少人知道的浮窗功能
  • 原文地址:https://www.cnblogs.com/boris1221/p/9718334.html
Copyright © 2011-2022 走看看