题7:出现k次与出现1次
- 数组中只有一个数出现了1次,其他的数都出现了k次,请输出只出现了1次的数。
具体思路:
- 创建一个字符二维数组
char[][] kRadix = new char[len][];
- 将arr[]的每一个数转换成三进制
Integer.toString(arr[i],k)
,并进行翻转-变为字符串-最后整成字符数组 - 同时要将最长的三进制数长度存储
if (kRadix[i].length > maxlen) maxlen = kRadix[i].length;
- 开辟一个新数组存放进制的不进位每一位的和
int[] resArr = new int[maxlen];
- 把全部数的三进制的每一位做不进位和放入数组resArr[maxlen]中
- 最后再用for遍历resArr[maxlen]%k * (int) (Math.pow(k, i),其实就是%k之后,如果3个相同的基本为0,只有相同数不为三的%k不为0,那么得出的就是只出现一次的数。
例子:
10进制:
2 、 9 、 7 、 3 、 6 、 0
3进制:
2 、 100 、 21 、 10 、0
反转(如果不进行反转就不能正确的位数进行相加)
2 、 001 、 12 、 01 、 0
位数相加(有3个相同的,要3个相加)
991
每位%3并*对应位数k次方(1*3^2)
得9
public class 出现k次与出现1次 {
public static void main(String[] args){
int[] arr = {2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
int len = arr.length;
char[][] kRadix = new char[len][];
int k = 3;
int maxlen = 0;
//转成k进制字符数组
//对于每个数字
for (int i = 0; i < len; i++){
//求每一个数字的三进制字符串并翻转,然后转为字符数组
kRadix[i] = new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
if (kRadix[i].length > maxlen)
maxlen = kRadix[i].length;
}
//不进位加法
int[] resArr = new int[maxlen];
for(int i = 0; i < len; i++){
// 不进位加法
for(int j = 0; j < maxlen; j++){
if(j >= kRadix[i].length)
resArr[j] += 0;
else
resArr[j] += (kRadix[i][j] - '0');
}
}
int res = 0;
for (int i = 0; i < maxlen; i++){
res += (resArr[i] % k) * (int) (Math.pow(k, i));
}
System.out.println(res);
}
}