当前位置:网站首页>笔试面试题目:求缺失的最小正整数
笔试面试题目:求缺失的最小正整数
2020-11-08 10:30:00 【osc_vuza8uho】
原文发表于:

国庆假期已过半。今天,我们来看一个leetcode问题,也是当年B公司的面试题,有难度。问题如下:
给定一个整数数组,找出其中缺失的最小的正整数,要求时间复杂度为O(n), 空间复杂度为O(1). 输入输出示例如下:
| 输入数组a | 输出 |
| [1, 2, 0] | 3 |
| [3, 4, 1, -1] | 2 |
| [6, 7, 8, 12] | 1 |

我们先来分析一下:
A. 假设a中的n个元素占满了1~n, 那么缺失的最小正整数就是n+1.
B. 假设a中的n个元素没有完全占满1~n, 那么缺失的最小正整数必然是1~n之间的某个数。
综合A和B可知:缺失的最小正整数必然在区间[1, n+1]中。这是一个非常重要的结论。
算法1:暴力算法
暴力算法很简单,直接遍历区间[1, n+1], 然后判断元素是否在a中。此时,时间复杂度是O(n*n), 空间复杂度为O(1).
显然,无法通过面试。
算法2:哈希算法
从暴力算法可知,这无非就是一个查找的问题,那么可以考虑用哈希表。也就是把a数组用哈希表来记录,然后直接遍历区间[1, n+1], 就可以判断元素是否在哈希表中。此时,时间复杂度和空间复杂度都是O(n).
显然,无法通过面试。
算法3:巧妙标记法
我们参考算法2,并在标记元素是否存在时做巧妙优化。
以a = [3, 4, 1, -1]为例,n = 4,过程如下:
| 原始数组 | [3, 4, 1, -1] |
| 非正数改为n+1 | [3, 4, 1, 5] |
| 3存在,用a[3-1]的负号来标识 | [3, 4, -1, 5] |
| 4存在,用a[4-1]的负号来标识 | [3, 4, -1, -5] |
| 1存在,用a[1-1]的负号来标识 | [-3, 4, -1, -5] |
| a[x-1]=4,是正数,故x必然不存在 | x=2便是缺失的最小正整数 |
可以看到,在记录元素x是否存在时,使用的是a[x - 1]的符号,其中,x的区间是[1, n]. 该算法的时间复杂度是O(n), 空间复杂度是O(1), 完全符合题目要求。 这种标记方式是非常巧妙的,而且确实不太容易想到。
既然算法的步骤确定了,那么对应的程序就相对简单了,来看一下:
package main
import "fmt"
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func solution(a []int) int {
n := len(a)
for i := 0; i < n; i++ {
if a[i] <= 0 {
a[i] = n + 1
}
}
for i := 0; i < n; i++ {
num := abs(a[i])
if num <= n {
a[num - 1] = -abs(a[num - 1])
}
}
for i := 0; i < n; i++ {
if a[i] > 0 {
return i + 1
}
}
return n + 1
}
func main() {
a := []int{3, 4, 1, -1}
fmt.Println(solution(a))
}
结果:2
算法4:置换归位法
算法3是比较难想到的,那么我们再看看更加直观的想法。对于数组a的元素i, 如果i在区间[1, n]中,可通过置换归位,把i放到a[i-1]处,如下:
| 输入数组a | 置换目标 |
| [1, 2, 0] | [1, 2, 0] |
| [3, 4, 1, -1] | [1, -1, 3, 4] |
| [6, 7, 8, 12] | [6, 7, 8, 12] |
置换后,再次遍历a, 如果a[x-1]和x不相等,那么,x肯定就是缺失的最小正整数,如下:
| 置换目标 | x(缺失的最小正整数) |
| [1, 2, 0] | 3 |
| [1, -1, 3, 4] | 2 |
| [6, 7, 8, 12] | 1 |
该算法的时间复杂度是O(n), 空间复杂度是O(1), 完全符合题目要求。既然算法确定了,那么对应的程序就相对简单了,如下:
package main
import "fmt"
func solution(a []int) int {
n := len(a)
for i := 0; i < n; i++ {
// 注意:下面这里要用for, 而不是if.
for a[i] > 0 && a[i] <= n && a[a[i]-1] != a[i] {
a[a[i]-1], a[i] = a[i], a[a[i]-1]
}
}
for i := 0; i < n; i++ {
if a[i] != i + 1 {
return i + 1
}
}
return n + 1
}
func main() {
a := []int{3, 4, 1, -1}
fmt.Println(solution(a))
}
结果:2
综上所述:算法1和算法2无法通过面试,算法3和算法4可以通过面试。其中,算法3是比较绕的,在面试现场不太容易想到。相比较而言,算法4直观易懂,在程序实现时要注意内层要用for, 而不是if.
总体来看,B公司的面试要求还是很高的,祝大家拿到心仪的offer.
版权声明
本文为[osc_vuza8uho]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4290163/blog/4707997
边栏推荐
- If you don't understand the gap with others, you will never become an architect! What's the difference between a monthly salary of 15K and a monthly salary of 65K?
- Python3.9的7个特性
- VC + + specified directory file output by time
- Rust: command line parameter and environment variable operation
- Px4 adds new applications
- 【计算机网络】学习笔记,第三篇:数据链路层(谢希仁版)
- 技术人员该如何接手一个复杂的系统?
- 仅用六种字符来完成Hello World,你能做到吗?
- Flink's sink: a preliminary study
- How did Julia become popular?
猜你喜欢

狗狗也能操作无人机!你没看错,不过这其实是架自动驾驶无人机 - 知乎

Adobe Prelude / PL 2020 software installation package (with installation tutorial)

糟糕,系统又被攻击了

Can you do it with only six characters?

413【毕设课设】基于51单片机无线zigbee无线智能家居光照温湿度传输监测系统

Mate 40系列发布 搭载华为运动健康服务带来健康数字生活

2天,利用下班后的4小时开发一个测试工具

laravel8更新之速率限制改进

Mate 40 series launch with Huawei sports health service to bring healthy digital life

python 循环区分(while循环和for循环)
随机推荐
python 循环区分(while循环和for循环)
Personal current technology stack
The difference between vivoy 73s and glory 30 Youth Edition
NOIP 2012 提高组 复赛 第一天 第二题 国王游戏 game 数学推导 AC代码(高精度 低精度 乘 除 比较)+60代码(long long)+20分代码(全排列+深搜dfs)
Adobe Prelude / PL 2020 software installation package (with installation tutorial)
Astra: Apache Cassandra的未来是云原生
211 postgraduate entrance examination failed, stay up for two months, get the byte offer! [face to face sharing]
Test requirements for MIC certification of Bluetooth 2.4G products in Japan
Astra: the future of Apache Cassandra is cloud native
IOS learning note 2 [problems and solutions encountered during the installation and use of cocopods] [update 20160725]
2天,利用下班后的4小时开发一个测试工具
墨者学院SQL注入解题
iOS 学习笔记二【cocopods安装使用和安装过程中遇到的问题及解决办法】【20160725更新】
Mozi college SQL injection solution
How does spotify drive data-driven decision making?
vivoy73s和荣耀30青春版的区别
[original] about the abnormal situation of high version poi autosizecolumn method
5g/4g工业无线路由器
Solve Safari browser download file name garbled problem
Seven features of Python 3.9