一道Java面试题的解答

从1到100 000 中任意拿掉两个数字,把剩下的99998个数顺序打乱,并且放入数组A中。 
要求只扫描一遍,把这两个数找出来;可以使用最多不超过5个局部变量,不能使用数组变量,并且不能改变原数组的值。
package m2010_09_14;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author qmhuang 2010-09-14
 *  从1到100 000 中任意拿掉两个数字,把剩下的99998个数顺序打乱,并且放入数组A中。
 *  要求只扫描一遍,把这两个数找出来;可以使用最多不超过5个局部变量,不能使用数组变量,并且不能改变原数组的值。
 */
public class Test2 {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		// 四个局部变量
		BigInteger x = BigInteger.valueOf(0);
		BigInteger y = BigInteger.valueOf(1);
		BigInteger sum = BigInteger.valueOf(0);
		BigInteger ji = BigInteger.valueOf(1);
		
		//先将1到10000存入到一个list里面,并一起将1到10000的和跟积求出来,保存到sum、ji
		for (int i = 1; i <= 10000; i++) {
			list.add(i);
			sum = sum.add(BigInteger.valueOf(i));
			ji = ji.multiply(BigInteger.valueOf(i));
		}
		//任意拿掉的两个数字
		list.remove(new Integer(10));
		list.remove(new Integer(2));
		
		//再次求出这个list的和跟积,保存到x、y
		for (Integer i : list) {
			x = x.add(BigInteger.valueOf(i));
			y = y.multiply(BigInteger.valueOf(i));
		}
		
		//求出拿掉两个数字的和跟积,保存在sum、ji
		sum = sum.subtract(x);
		ji = ji.divide(y);
		
		//假设这两个数为a、b,则他们满足a+b=sum,a*b=ji,因此
		//i.intValue() % i == 0	&& (ji.intValue() / i + i) == sum.intValue()这个就是我们的条件
		for (int i = 1; i < sum.intValue(); i++) {
			if (ji.intValue() % i == 0
					&& (ji.intValue() / i + i) == sum.intValue()) {
				System.out.println("这两个数为:" + i + "、" + ji.intValue() / i);
			}
		}
	}
}

上面我没有用数组,觉得数组比较麻烦就用了List,还有就是在写的过程中发现老是出现,什么结果都变成0了,原来是在求积的时候,超出了int的范围,没多想改用long,结果还是超出,后来就直接用了BigInteger。我觉得我这求出积,再得到拿掉的两个数的积方法很不好,不知道大家有什么好的方法没有?

你可能感兴趣的:(java,面试)