5.7

Topic 5.7 An array A contains all the integers from 0 to n except for one number which is missing. In this problem, we cannot access an entire integer in A with a single operation. The elements of A are represented in binary, and the only operation we can use to access them is “fetch the jth bit of A[i]”, which takes constant time. Write code to find the missing integer. Can you do it in O(n) time?

引申问题1Given a list of numbers from 0 to n, with one number removed, find the missing number.

è Sum all numbers, compare it to the sume of 0 through nn*(n-1)/2. The difference is the missing number.

方法1 Computing the value of each number, based on its binary representation, and calculate the sum. Time: O(nlog(n))----n*length(n), length is the number of bits in n. length(n)=log2(n).

方法2 Removing a number creates an imbalance of 1s and 0s in the least significant bit, LSB1.

1)  If n is odd, count(0s)=count(1s); If n is even, count(0s)=1+count(1s)

2)  If n is odd & the removed number is odd, count(0s)>count(1s);

If n is odd & the removed number is even, count(0s)<count(1s);

If n is even & the removed number is odd, count(0s)>count(1s);

If n is even & the removed number is even, count(0s)=count(1s);

->Discard the unsatisfied n/2 numbers.

3)  Repaet and count LSB2, ..LSBn, we look at n, then n/2, then n/4 and so on. Time: O(n).

public class BitInteger {
		public static int INTEGER_SIZE;
		private boolean[] bits;
		public BitInteger() {
			bits = new boolean[INTEGER_SIZE];
		}
		/* Creates a number equal to given value. Takes time proportional 
		 * to INTEGER_SIZE. */
		public BitInteger(int value){
			bits = new boolean[INTEGER_SIZE];
			for (int j = 0; j < INTEGER_SIZE; j++){
				if (((value >> j) & 1) == 1) bits[INTEGER_SIZE - 1 - j] = true;
				else bits[INTEGER_SIZE - 1 - j] = false;
			}
		}

		/** Returns k-th most-significant bit. */ 
		public int fetch(int k){
			if (bits[k]) return 1;
			else return 0;
		}

		/** Sets k-th most-significant bit. */
		public void set(int k, int bitValue){
			if (bitValue == 0 ) bits[k] = false;
			else bits[k] = true;
		}

		/** Sets k-th most-significant bit. */
		public void set(int k, char bitValue){
			if (bitValue == '0' ) bits[k] = false;
			else bits[k] = true;
		}

		/** Sets k-th most-significant bit. */
		public void set(int k, boolean bitValue){
			bits[k] = bitValue;
		}	

		public void swapValues(BitInteger number) {
			for (int i = 0; i < INTEGER_SIZE; i++) {
				int temp = number.fetch(i);
				number.set(i, this.fetch(i));
				this.set(i, temp);
			}
		}

		public int toInt() {
			int number = 0;
			for (int j = INTEGER_SIZE - 1; j >= 0; j--){
				number = number | fetch(j);
				if (j > 0) {
					number = number << 1;
				}
			}
			return number;
		}
	}
import java.util.ArrayList;

public class c5_8 {
	public static ArrayList<BitInteger> initialize(int n, int missing) {
		BitInteger.INTEGER_SIZE = Integer.toBinaryString(n).length();
        ArrayList<BitInteger> array = new ArrayList<BitInteger>();
        
        for (int i = 1; i <= n; i++) {
        	array.add(new BitInteger(i == missing ? 0 : i));
        }
        
        return array;	
	}
	
	 public static int findMissing(ArrayList<BitInteger> array) {
	       return findMissing(array, BitInteger.INTEGER_SIZE - 1);
	    }        
	
	 private static int findMissing(ArrayList<BitInteger> array, int column) {//从最高位开始堆栈,打印是从最高位开始的
		 if (column < 0) { // Base case and error condition
	    		return 0;
	    	}
		
		 ArrayList<BitInteger> oneBits = new ArrayList<BitInteger>(array.size()/2);//它是一个存了尾数是1的数的数组
	     ArrayList<BitInteger> zeroBits = new ArrayList<BitInteger>(array.size()/2);//它是一个存了尾数是0的数的数组
	        for (BitInteger a : array) {
	            if (a.fetch(column) == 0) {//fetch的是当前位,仅一位
	                zeroBits.add(a);
	            } else {
	                oneBits.add(a);
	            }
	        }
	        if (zeroBits.size() <= oneBits.size()) {//说明缺0
	        	int v = findMissing(zeroBits, column - 1);
	        	return (v<<1)|0;//左移一位,跟0或,让最右边是0
	        }else {
	            	int v = findMissing(oneBits, column - 1);//说明缺1
	            	return (v<<1)|1;//左移一位,跟1或,让最右边是1
	        	}
		 
	 }
		 public static void main(String[] args) {
		        int n = 35;
		        int missing = 14;
		        ArrayList<BitInteger> array = initialize(n, missing);
		        System.out.println("The array contains all numbers but one from 0 to " + n);
		        System.out.println("The missing number is:  "+findMissing(array));		      
	 }
}
//结果
The array contains all numbers but one from 0 to 35
The missing number is:  14



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值