题目:给定一个无序的整数数组,怎么找到第一个大于0,并且不在此数组的整数。比如[1,2,0]返回3,[3,4,-1,1]返回2,[1, 5, 3, 4, 2]返回6,[100, 3, 2, 1, 6,8, 5]返回4。要求使用O(1)空间和O(n)时间。
思路:时间复杂度确切的说是O(2N)(循环部分),去掉常亮就是O(N)
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int Calculate(vector<int> arr)
{
int l = arr.size();
int i=0;
while (i < l)
{
if (arr[i]-1 == i) {
++i;
}
// 这个判定式的意思:当前的值大于位置的INDEX值,
// 并且当前值小于当前最大的INDEX值,
// 并且与被交换的位置的值不相等
else if (arr[i]-1 > i && arr[i]-1 < l && arr[i] != arr[arr[i]-1]) {
swap(arr[i], arr[arr[i]-1]);
}
else {
swap(arr[i], arr[l-1]);
--l;
}
}
return i+1;
}
int main(int argc, char ** argv)
{
vector<int> arr = {1,2};
cout << Calculate(arr) << endl;
}
该算法的核心思想是,首先,第一个大于0的数并且不再数组中,那么该数一定是小于等于数组的长度,所以对于数组中的每个数,只要该数小于数组的长度,那么就归位(恢复到该数-1的下表位置), 使用Python的解法如下:
def Calculate(l):
len_l = len(l)
for idx, item in enumerate(l):
if item <= len_l and item > 0:
l[item - 1], l[idx] = item, l[item - 1]
for idx, item in enumerate(l):
if item <= len_l and item > 0:
l[item - 1], l[idx] = item, l[item - 1]
rt = len_l
for idx, item in enumerate(l):
if idx + 1 != item:
rt = idx + 1
break
return rt
if __name__ == '__main__':
l = [1, 5, 3, 4, 2]
print(Calculate(l))