进制运算例题
一整数数列中某一数字出现1次,其他数字都出现K次,输出出现1次的数字。
思路
明确一个性质K进制的K个相同数字不进位相加,其结果为0。
以两个3的二进制为例
所以,用进制运算解此题,可以将数组中每个数字转为K进制然后相加,所得结果为出现1次数字的K进制,最后将结果转为2进制输出即可。
需要注意的是:
1.不进位加法的写法:转换为K进制后,每列相加之和模K。
2.运用二维数组进行每列相加时,每列之和建议保存在一维数组中。
3.运用二维数组进行每列相加时,注意当前行的高低位是否与其他行对齐。(可以反转数字保证每行高低位对齐)
/*
* 性质1:K进制的K个相同的数不进位相加,其结果为0
* 需求1:进制转换K(2转K,K转2)
* 需求2:不进位加法(模K)
*/
public class 出现1次与出现K次的进制解法 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = { 2, 2, 2, 9, 7, 7, 7, 3, 3, 3, 6, 6, 6, 0, 0, 0 };// k = 3
// K进制转换
int k = 3;
int len = arr.length;
int maxLen = 0; // 记录数字转换为3进制后的最大长度
char[][] kRadix = new char[len][];
for (int i = 0; i < kRadix.length; i++) {
kRadix[i] = new StringBuilder(Integer.toString(arr[i], k)).reverse().toString().toCharArray(); // 反转以对齐高低位
if(kRadix[i].length > maxLen){
maxLen = kRadix[i].length;
}
}
// 不进位加法
int[] ansArr = new int[maxLen];// 用于保存每列之和
for(int i = 0; i < len; i++){
for(int j = 0; j < maxLen; j++){
if(j >= kRadix[i].length){
ansArr[j] += 0;
}else{
ansArr[j] += (kRadix[i][j] - '0');
}
}
}
StringBuilder res = new StringBuilder();
for(int i = ansArr.length - 1; i >= 0; i--){
ansArr[i] = ansArr[i] % k;// 列之和mod K
res.append(ansArr[i]);
}
// 转2进制后输出
System.out.println(Integer.parseInt(res.toString(), 3));
}
}