Leetcode#41 First Missing Positive

本文介绍了一种巧妙的方法,在O(1)空间复杂度下找到未排序数组中缺失的最小正整数。通过原地交换元素至其正确位置,再扫描数组找出第一个不在正确位置的元素,即为所求。文章提供了详细的算法思路及代码实现。

原题地址

 

非常有技巧的一道题,如果没有接触过类似题目或没有任何提示的情况下想出来很困难,因为题目要求O(1)的空间复杂度

既然是O(1)的空间复杂度,自然要用到原数组了。

解法是:

1. 遍历每个数组元素,把元素都交换到正确的位置上。比如发现A[3] = 5,则交换A[5]和A[3],让A[5]=5。

2. 再遍历一次,遇到第一个A[i] != i就是所求解

当然,交换过程是个迭代过程,有可能交换一次之后发现还可以交换,则继续交换下去,直到没法交换了。

什么情况下停止交换?

1. 遇到0或负数。这种数字没有对应的位置

2. 遇到比n大的数字。

 

有一个小技巧:如果发现当前位置的数字过大(即对于任意位置i有A[i] > i),则不需要交换,因为迟早会把A[i]交换到正确的位置上的。

比如A[3]=5,假如3存在,则后面肯定会遇到某个位置k且A[k]=3,此时会将A[3]和A[k]交换,交换后A[k]=5。

如果k<5,交换A[k]和A[5],结果是A[5]=5

如果k>5,又回到了一开始的情况,停止交换

利用这个技巧可以简化代码,但是不会提高效率。

 

代码:

 1 int firstMissingPositive(int A[], int n) {
 2   for (int i = 0; i < n; i++)
 3     while (A[i] <= i && A[i] > 0 && A[i] != A[A[i] - 1])
 4       swap(A[i], A[A[i] - 1]);
 5 
 6   for (int i = 0; i < n; i++)
 7     if (A[i] != i + 1)
 8       return i + 1;
 9   return n + 1;
10 }

 

PS: 上述代码还不完美,A[i] != A[A[i] - 1] 和 A[i] <= i 这两个条件其实可以整合在一起。以后刷第三遍的时候再改吧。

转载于:https://www.cnblogs.com/boring09/p/4245977.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值