现在的位置: 首页 > 综合 > 正文

CI5.7-寻找丢失的数

2019年03月07日 ⁄ 综合 ⁄ 共 948字 ⁄ 字号 评论关闭

一个整形数组A[1...n]包含0~n中的n个数,有一个数丢失。规定不可以通过A[i]获取对应的整数,可以使用的唯一的操作是fetch(i, j),该函数表示获得A[i]的第j个bit的值(即二进制形式中的第j个bit)。假定fetch(i, j)的操作是常数的,如何在O(n)的时间内找出丢失的整数。

思路:

从0到n一共n+1个整数,用N0表示这n+1个整数中最低有效位为0的整数个数,用N1表示这n+1个整数中最低有效位为1的整数个数,那么N0和N1可能有一下两种关系:N0 = N1 或 N0 = N1 + 1。

如果丢失的数为奇数,则有:N0 = N1 + 1 或 N0 = N1 + 2,即:N0 > N1。如果丢失的数为偶数,则有:N0 = N1 - 1 或 N0 = N1,即:N0 <= N1。所以通过N0和N1的关系就可以确定丢失的整数的最低有效位是0还是1,这样就可以淘汰一半的整数。然后检查次低有效位的数字、第三低有效位的数字等等,以此类推就可以得到丢失的数字。

int FindMissing(const vector< vector<int> >& v)
{
	vector<bool> flag(v.size(), 0);
	vector<int> miss;
	for (int j = 0; j < 32; ++j)
	{
		int n0 = 0, n1 = 0;
		for (int i = 0; i < v.size(); ++i)
		{
			if ((flag[i] == false) && (fetch(i, j) & 1 == 1))
				++n1;
			else if ((flag[i] == false) && (fetch(i, j) & 1 == 0))
				++n0;
		}
		if (n1 >= n0)
		{
			for (int k = 0; k < v.size(); ++k)
			{
				if ((flag[k] == false) && (fetch(k, j) & 1 == 1))
					flag[k] = true;
			}
			miss.push_back(0);
		}
		else
		{
			for (int k = 0; k < v.size(); ++k)
			{
				if ((flag[k] == false) && (fetch(k, j) & 1 == 0))
					flag[k] = true;
			}
			miss.push_back(1);
		}
	}
	int res = 0;
	for (int i = 0; i < miss.size(); ++i)
	{
		if (miss[i] == 1)
			res |= (miss[i] << i);
	}
	return res;
}

抱歉!评论已关闭.