zoukankan      html  css  js  c++  java
  • 寻找失踪的整数数组(Find the missing integer)

    排列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);
    }

    如果不清楚欢迎讨论。

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

  • 相关阅读:
    多线程
    泛型
    枚举、注解
    重写comparater比较器
    Arrays工具类和Collections工具类
    重写equals和hashCode的方法
    遍历集合的方法
    关键字总结
    having 的用法
    HTTP协议
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4633903.html
Copyright © 2011-2022 走看看