博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
First Missing Positive
阅读量:2425 次
发布时间:2019-05-10

本文共 2104 字,大约阅读时间需要 7 分钟。

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 ) O(n) O(n) time and uses constant extra space.

分析

给出一个无序的int类型数组,要求出其缺失的最小正整数。要求时间复杂度为 O ( n ) O(n) O(n)。并且需要的额外空间只能是常量大小。

如果没有后面的要求,这道题还是很简单的,但是有了后面时间复杂度和空间复杂度的要求,难度就变为hard了。

不符合要求的解法:

  • 使用普通的排序,然后从头到尾遍历即可。此时时间复杂度为 O ( n ∗ l o g n ) O(n*logn) O(nlogn)
  • 由于是int类型,我们可以使用桶排序的方式,虽然此时时间复杂度为 O ( n ) O(n) O(n),但额外空间过大。

正确的解法:

在常量大小的额外空间时,排序算法的时间复杂度最小为 O ( n ∗ l o g n ) O(n*logn) O(nlogn),因此,不能使用排序算法。
要达到时间复杂度为 O ( n ) O(n) O(n)的要求,这意味着我们只能对该数组进行少量次数的遍历。

注意到题目要求的是找出缺失的最小正整数。假如没有重复的数,并且数组已经排好序了。如果没有缺失的数,那么第i个元素的值应该是i + 1(因为0不属于正整数);那么最小缺失的正整数,应该是第一个nums[i]不等于i + 1本来应该的值,即i + 1。如果没有缺失,那么就是nums.length + 1

因此,我们只需要遍历数组,将每个元素的值放置到正确的位置。然后再遍历一次,找出第一个不符合要求的位置即可。

那么,对于不符合要求的数应该放置再哪里呢?注意到一个事实,如果第i个元素不符合要求,那么之后的元素如何放置都没有关系(因为我们找的是第一个不符合要求的)。

所以我们可以从右到左遍历整个数组,对于第j个元素

  • 如果当前元素的值小于等于0(要的是正整数)或者是当前元素的值大于j + 1,则说明当前元素不符合要求,继续向左遍历(j--)。
  • 如果当前元素的值等于j + 1,说明该位置放对了,不需要改变,也是继续向左遍历。
  • 如果当前元素的值temp大于0并且小于j + 1。那么他应该被放置到nums[temp - 1]的位置,然后将当前元素的值置为nums[temp - 1]原本的值。如果考虑到有重复的元素,即nums[temp - 1]原来的值为temp(已经正确放置),此时也不需要改变当前元素的值,继续向左遍历即可。
  • 遍历完成后,重新遍历一遍,找出第一个nums[j] != j + 1的位置,然后返回j + 1即可。如果都符合,返回nums.length + 1

对于这种解法,总共需要遍历两遍,在第一次遍历的时候,有可能对于某个位置j,需要替换前面所有的元素(替换j - 1次,最差情况,这时总共需要遍历3遍,但时间复杂度也是 O ( n ) O(n) O(n))。时间复杂度为 O ( n ) O(n) O(n)。替换时均在原来的数组上进行,空间复杂度为 O ( 1 ) O(1) O(1)。符合题目要求。

代码如下

class Solution {
public int firstMissingPositive(int[] nums) {
int temp = 0; int j = nums.length - 1; while (j >= 0) {
temp = nums[j]; // 如果没有缺失,第 j 个位置的值应该是 j + 1 if (temp <= 0 || temp >= j + 1) {
// 该位置的值符合要求或者是超出范围 j--; } else if (nums[temp - 1] == temp) {
// 有重复元素 j--; } else {
// 将 nums[j] 放到正确的位置 nums[j] = nums[temp - 1]; nums[temp - 1] = temp; } } // 寻找不符合要求的位置 for (j = 0; j < nums.length; j++) {
if (nums[j] != j + 1) {
return j + 1; } } return j + 1; }}

转载地址:http://bibmb.baihongyu.com/

你可能感兴趣的文章
云评测 | 开发者最有用的开源云监控工具有哪些呢? 这7款神器总有一款适合你!...
查看>>
小团队的微服务之路
查看>>
K8S精华问答 | Kubernetes集群不能正常工作,难道是防火墙问题?
查看>>
5G精华问答 | 什么是5G?5G与LTE有什么关系?
查看>>
虎牙直播在微服务改造方面的实践和总结
查看>>
微服务精华问答 | 在使用微服务架构时,您面临哪些挑战?
查看>>
Kubernetes 调度器实现初探
查看>>
边缘计算精华问答 | 边缘计算有哪些应用场景?
查看>>
要闻君说:Synergy Research Group首发云基础设施数据,腾讯云v5一把;京东物流发力5G;厉害!阿里挖走贾扬清...
查看>>
要闻君说:重磅!阿里巴巴发布了机器学习平台PAI 3.0版本;厉害!三星推出了业界首款HBM2E内存;Google也做云游戏平台...
查看>>
没有新芯片,没有大核弹,黄教主这次给大家带来了个PRADA
查看>>
VMware vSphere 6.7主机与虚拟机高级管理
查看>>
数据中台精华问答 | 数据中台和传统数仓的区别是什么?
查看>>
这是一则计算机视觉顶级会议CVPR与腾讯的爆闻,啥?
查看>>
如何用30分钟快速优化家中Wi-Fi?阿里工程师有绝招
查看>>
三星计划替换所有日产半导体材料;美企过度响应“禁令”,华为被曝祭出数亿索赔;苹果iPhone 11发布日期刚刚泄露...
查看>>
帮助你驾驭 Kubernetes 的 4 个工具 | Linux 中国
查看>>
Storm精华问答 | storm与Hadoop区别?
查看>>
正式发布!鸿蒙,来了!
查看>>
项目是如何死掉的?太过真实!
查看>>