数组中未出现的最小正整数
来源:互联网 发布:男人月薪4500 知乎 编辑:程序博客网 时间:2024/03/29 14:23
题目:数组中未出现的最小正整数
给定一个无序整型数组arr,找到数组中未出现的最小正整数。要求时间复杂度为O(N),空间复杂度为O(1)。
例如:
arr=[-1,2,3,4]。返回1。
arr=[1,2,3,4]。返回5。
分析:
最小正整数是1,所以常规的方法就是在数组中找1,然后是2,依次找下去...。一直找到第一个没有出现的正整数,这个数就是未出现的最小的正整数。但是这样的时间复杂度为O(N*N)。
题目要求时间复杂度为O(N),空间复杂度为O(1)。就是说数组只能从头到尾变遍历一次,而且不能构造新数组copy原数组中的数。
此题目为乐视网2016校园招聘软开笔试题的最后一道题,笔者当时就挂在这道题上,以至于没有面试机会。后来经过一番研究终于把题目做出来了,主要是参考了《程序员代码面试指南》(左程云编写的)中的解析思路,现在分享给大家。
最理想的状况是数组已经排好序了且非负,此时从头到尾遍历数组,找到第一个值不等于下标+1的数,下标+1就是那个未出现的最小正整数。
如下表
0
1
2
3
4
1
2
4
7
8
arr[5] = {1,2,4,7,8}
其中arr[0] = 1 = 0 + 1;
arr[1] = 2 = 1 + 1;
arr[2] = 4 != 2 + 1;
故未出现的最小正整数为2 + 1 = 3。
但题目给的是无序整形数组,理想状况发生的概率几乎为零,不能直接用上述方法找出,我们只能把所有可能出现的情况都分析一遍。
(1) arr为整数1,2,3…N的一个随机排列,那个未出现的最小正整数就是N+1。
(2) arr中有小于1或者大于N的数出现(我们称之为“不合法”的数),则未出现的最小正整数一定在1到N中间(因为数组一共只有N个数,如果出现不合法的数,则出现的1到N之间的数的个数一定小于N,故一定有没有出现的数)。
基于以上分析,具体实现过程如下:
(1) 先设置两个变量L,R。
L表示已经从1到L已经出现(左边界),L的初值为0。如果一个数字过大(不合法),就会被扔掉,用R表示这个右边界,即大于R的数会被扔掉。R的初值为N,表示从1到R的元素都不会被扔掉,大于R的就会被扔掉。但是这个R的值是变化的,如果L+1到R中有一个元素不合法,那么R--,因为最多只能放下R-1个合法数。
也就是说,1到L上的数已经出现,[L+1,R]区间上的数未出现但可能会出现。
(2) 从左开始遍历数组元素,遍历到L时,若arr[L]= L + 1,由于L表示前面已经出现的正整数,则说明1到L+1均出现,L++;若arr[L]<=L,R--;若arr[L]>R,arr[L] = arr[R-1],R--;
(3) 若arr[arr[L]-1]==arr[L],说明有重复值,,arr[L] = arr[R-1],R--;
(4) 若以上情况均未发生,交换arr[L]与arr[arr[L]-1],继续从L开始遍历。
(5) 最后L=R,返回L+1。
具体代码实现如下
:
#include<stdio.h>
int missMinNum(int arr[], int n)
{
int l = 0;
int r = n;
int temp;
while(l < r)
{
if(arr[l] == l +1) {
l++;
}
else if(arr[l]> r || arr[l] <= l || arr[arr[l] - 1] == arr[l])//不合法
{
arr[l] =arr[--r];
}
else//合法但是没有在理想的位置上
{
temp = arr[l];
arr[l] =arr[arr[l] - l];
arr[arr[l] - l] =arr[l];
}
}//while
return l + 1;
}
int main(void)
{
int a[6] ={1,3,5,-1,4,7};
int n = 6;
printf("%d\n",missMinNum(a,n));
return 0;
}
- 数组中未出现的最小正整数
- 数组中未出现的最小正整数
- 数组中未出现的最小正整数
- 数组中未出现的最小正整数
- 数组中未出现的最小正整数
- 数组中未出现的最小正整数
- 数组与矩阵---数组中未出现的最小正整数
- 数组中未出现的最小正整数(算法)
- 求数组中未出现的最小正整数
- 求数组中未出现的最小正整数
- 数组中为出现的最小正整数
- 41. First Missing Positive(找到数组中未出现的最小正整数)
- 数组中未出现的最小正整数(时间复杂度O(N),空间复杂度O(1))
- 找到数组中未出现的最小整数
- 数组中缺失的最小正整数
- 算法题:未出现最小正整数
- 给定一个无序整型数组,找出数组中未出现的最小整数
- 寻找不在数组中最小的正整数 First Missing Positive
- HDU 4433 locker
- Letter Combinations of a Phone Number
- igrimaceV8.0.0 IG (三个插件安装方式)
- 达内学习日志Day20:Java核心API(Map初体验)
- Linux网络编程---ICMP协议分析及ping程序实现
- 数组中未出现的最小正整数
- 二级指针
- SparkSQL之数据源
- AFN文档中文翻译以及简单使用说明
- C#学习之多线程开发技术(九)
- 第6周—项目5 后缀表达式
- Java高级_网络编程
- 纠正对Fragment Transaction BackStack的误解
- 又开了一个C语言最强最全班