Cracking the coding interview--Q5.7

原文:

An array A[1…n] 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?

译文:

数组A[1…n]包含0到n的所有整数,但有一个整数丢失了。在这个问题中, 我们不能直接通过A[i]取得数组中的第i个数。数组A被表示成二进制, 也就是一串的0/1字符,而我们唯一能使用的操作只有“取得A[i]中的第j位”, 这个操作只需要花费常数时间。写程序找出丢失的整数,你能使程序的时间复杂度是O(n)吗?


题目中所述数组A被表示成二进制,也就是说数组A所有每个元素都是32位表示,不能直接通过A【i】来直接获取元素的值,

唯一能使用的操作只有“取得A[i]中的第j位”,这是已知条件,可以利用这个条件来获取A【i】的32位每一位的数,这样也

就可以计算出数组A【i】的值。


package chapter_5_BitManipulation;

import java.util.Scanner;

/**
 * 
 * 数组A[1…n]包含0到n的所有整数,但有一个整数丢失了。在这个问题中, 我们不能直接通过A[i]取得数组中的第i个数。
 * 数组A被表示成二进制,
 * 也就是一串的0/1字符,而我们唯一能使用的操作只有“取得A[i]中的第j位”, 
 * 这个操作只需要花费常数时间。写程序找出丢失的整数,你能使程序的时间复杂度是O(n)吗?
 *
 */
public class Question_5_7 {
	
	/**
	 * @param a
	 * @param k
	 * @param i
	 * @return
	 * 
	 * 负责通过位运算获取数组k的二进制具体位上的值
	 * 
	 */
	public static int fetch(int a[], int k, int i) {
		int m = a[k];
		for(int j=0; j<i; j++) {
			m >>=1;
		}
		return m & 1;
	}
	
	/**
	 * @param a
	 * @param k
	 * @return
	 * 
	 * 负责获取数组A中第k下标的数
	 * 
	 */
	public static int getValue(int a[], int k){
		int sum = 0;
		int p = 1;
		int m = a[k];
		for(int i=31; i>=0; i--) {
			sum = (sum << 1) | fetch(a, k,  i);
		}
		return sum;
	}
	
	/**
	 * @param a
	 * @return
	 * 
	 * 找出缺失的元素值
	 * 
	 */
	public static int find_missing(int a[]) {
		boolean bool[] = new boolean[a.length + 1];
		for(int i=0; i<bool.length; i++) {
			bool[i] = false;
		}
		for(int i=0; i<a.length; i++) {
			bool[getValue(a, i)] = true;
		}
		int j = 0;
		for(; j<bool.length; j++) {
			if(bool[j] == false) {
				break;
			}
		}
		return j;
	}
	
	public static void main(String args[]) {
		int a[] = {0,1,2,3,5};
		int result = find_missing(a);
		System.out.println("缺少的是:" + result);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值