package com.ausky.work.pongo;
/**
* 最近看到一道面试题:给定 1-n 内的不重复的 n-1个数 求出少的那个数 举例:n = 5,给4个数 1,3,4,5 那么显然 少的就是 2 分析:
* 给定的n-1个数 并不是已经排好序的 所以 如果先进行排序 再 比较的话 那么时间复杂度 就是 n*lgn 所以先排序的办法 暂时搁置
*
* @author xn-hyao-01
*
*/
public class FindLostNum {
/**
* 方法1 :使用加法 1+2+...+n = (n+1)*n/2 缺点 n 很大的时候 n*n 就会更加大 是一个庞大的数字 有可能超出 精度
* 等等问题
*
* @param array
* @return
*/
public long useAdd(int[] array, int n) {
long sum = 1l;
for (int tmp : array) {
sum += tmp;
}
// 防止溢出 乘以 一个 long 1
return n * (1l) * (n + 1) - sum;
}
/**
* 方法2: 使用枚举法 定义一个n位的数组 tmpArray [0,0,0...,0]; 然后取 array的数 x 然后将
* tmpArray[x-1] = 1; 缺点:貌似 数据量很大的时候 不可行 另外一总猜想:设置
* 2维数组,tmpArray[n/1000+1][1000]; 这个不知道会不会出问题 但是也感觉挺不好的 大数据量 枚举不靠谱
*
* @param array
* @return
*/
public int useMinus(int[] array, int n) {
int[] tmpArray = new int[n];
for (int tmp : array) {
tmpArray[tmp - 1] = 1;
}
int res = 0;
for (int i = 0; i < n; i++) {
if (tmpArray[i] == 0) {
res = i + 1;
}
}
return res;
}
/**
* 方法3: 提示说可以使用异或 进行解答 1.....n个数 与 1,....n,进行异或 结果为0 那么将他们进行异或 得到的结果
* 不就是少了的那个嘛
*
* @param array
* @param n
* @return
*/
public int useXor(int[] array, int n) {
int i = 1;
int res = 0;
for (int tmp : array) {
res = res ^ i ^ tmp;
i++;
}
res = res ^ i;
return res;
}
}