寻找失踪的整数数组(Find the missing integer)

本文介绍了一种在线性时间内找出数组中缺失整数的算法。该算法利用了数组元素的奇偶特性,通过多次扫描缩小搜索范围,最终确定缺失的整数。文中还提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排列a包含N分子,其元素属于[0,N]之间,且不存在反复的元素。请你找出数组中缺失的元素(由于[0,N]之间有N+1个元素。而数组仅仅能存储N个元素。所以必定缺少一个元素)。当中对数组的操作满足下列的条件:不能在常数时间内读取数组中的元素,可是可以读取数组中元素的某一个bit值。可以在常数时间内交换数组的两个元素的位置。请设计一种算法使其可以在线性时间内找出数组中缺失的元素。

(N=2^k)

An array a[] contains all of the integers from 0 to N, except 1. However, you cannot access an element with a single operation. Instead, you can call get(i, k) which returns the kth bit of a[i] or you can call swap(i, j) which swaps the ith and jth elements of a[]. Design an O(N) algorithm to find the missing integer. For simplicity, assume N is a power of 2

算法设计:有题设可知,[0,N]之间奇数和偶数个数之差等于1,假设缺失偶数,则奇数和偶数的数目相等,反之缺失奇数。

怎样推断元素的奇偶呢?题设给出仅仅能在常数时间内訪问数组元素的某个bit值。所以仅仅需看元素的最后一个bit为0还是1就可以。这样通过一次扫描数组能够排除n/2个元素。

利用此法(推断0,1个数的多少)我们就能够找出缺失的元素。反复上述操作就可以。

算法性能分析:

第一次扫面元素推断奇偶。须要循环n次。从而排除n/2个元素,因此第二次循环须要循环n/2次,一次类推。总共的循环次数为T

T=n+n/2+n/4+n/8+……+1=O(n)。为此达到了题目的要求。

算法实现:

void swap(int* a, int i, int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}
int get(int* a, int i, int k)
{
	int res = a[i]>>k & 1;
	return res;
}
int Find_the_missing_integer(int* a, int low, int high)
{
	int res = 0;
	int power = 1;
	int count0 = 0;
	int count1 = 0;
	int n = high-low+1;
	int pointer0 = 0;
	int i=0;
	while(n>0)
	{
		for(int j=low; j<=high;j++)
		{
			if(get(a,j,i) == 0)
			{
				count0++;
				swap(a,j,pointer0);
				pointer0++;
			}
			else
			{
				count1++;
			}
		}
		if(count0>count1)
		{
			res = res + power*1;
			low = pointer0;
			n = count1;
		}
		else
		{
			res = res + power*0;
			high = pointer0 - 1;
			pointer0 = low;
			n = count0;
		}
		power = power*2;
		count0 = 0;
		count1 = 0;
		i++;
	}
	return res;
}

算法解释:find_the_missing_intger,函数中利用pointer记录最后一个元素的0还是1的分界点。然后每次都循环扫面满足我们要求的那一部分元素,直到终于没有元素位置。

測试代码:

#include <iostream>
using namespace std;
void swap(int* a, int i, int j);
int get(int* a, int i, int k);
int Find_the_missing_integer(int* a, int low, int high);
void main()
{
	int a[]={1,2,3,4,5,6,7,0};
	cout<<Find_the_missing_integer(a,0,7);
}

如果不清楚欢迎讨论。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值