1、找出数组中唯一成对的那个数
1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现
一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空
间,能否设计一个算法实现?
思路1:按位异或再异或得到重复的那个数
int n=11;
int[] arr = new int[n];
int index = new Random().nextInt(n);
arr[arr.length-1]=new Random().nextInt(n-1)+1;
for(int i=0; i<arr.length-1; i++) {
arr[i]=i+1;
}
int num=0;
for(int i=1; i<n; i++) {
num = (num ^ i);
}
for(int i=0; i<n; i++) {
num = num ^ arr[i];
}
for(int i=0; i<n; i++) {
System.out.print(arr[i]+",");
}
System.out.println("\n"+num);
思路2:暴力求解,利用数组存储
//开辟一个存储空间将数值作为下标进行遍历
int[] helper = new int[n];
for(int i=0; i<n; i++) {
helper[arr[i]]++;
}
for(int i=0; i<n; i++) {
if(helper[i]==2) {
System.out.println(i);
break;
}
}
2、二进制中1的个数
请实现一个函数,输入一个整数,输出该数二进制表示中1 的个数
例:9的二进制表示为1001,1的个数为2
思路1:整数32位,左移和1进行‘与’运算
思路2:数减一,使低位上1变为0,其后变为1,之后再与原数做‘与’运算,使后面的1变为0,count++,直到数值变为0
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//Integer.toString(int par1,int par2)
//par1表示要转成字符串的数字,par2表示要转成的进制表示
System.out.println(Integer.toString(n,2));
int count = 0;
//1向左移动
for(int i=0; i<32; i++){
if((n&(1<<i)) == (1<<i)) {
count++;
}
}
//数字向右移动
for(int i=0; i<32; i++){
if(((n>>i)&1) == 1) {
count++;
}
}
System.out.println(count);
public static void method2(int n) {
int count = 0;
while(n!=0) {
n = (n&(n-1));
count++;
}
System.out.println("method2:"+count);
}
3、2的整数次方
用一条语句判断一个整数是不是2的整数次方
思路:该整数的二进制表示中只有一个‘1’,利用题2思路,减一应为0
if(((n-1)&n) == 0) {
System.out.println("yes");
}
else {
System.out.println("no");
}
4、将整数的奇偶位互换
public static void main(String[] args) {
int a = 6;
int b = m(a);
System.out.println(Integer.toString(a, 2));
System.out.println(Integer.toString(b, 2));
System.out.println(b);
}
public static int m(int i) {
//0x为16进制,8个a为8个1010即int的32位
//和1010 1010 1010 。。。。。做与运算取出偶数位
int ou = i&0xaaaaaaaa;
//和0101 0101 0101 。。。。。做与运算取出奇数位
int ji = i&0x55555555;
return (ou>>1)^(ji<<1);//异或连起来
}
0110
1001
9
5、0~1间浮点实数的二进制表示
题:给定一个介于0和1之间的实数,类型为double,打印它的二进制表示,若该数字无法精确地用32位以内的二进制表示,则打印“ERROR”
思路:乘2,判断整数位,消除整数位,直至减为0
public static void main(String[] args) {
double num = 0.625;
StringBuilder sb = new StringBuilder("0.");
while(num>0) {
double x = num*2;
if(x>=1) {
sb.append("1");
num = x-1;
}
else {
sb.append("0");
num = x;
}
if(sb.length() > 34) {
System.out.println("ERROR");
return;
}
}
System.out.println(sb);
System.out.println(sb.toString());
}
6、出现k次与出现1次
题:数组中只有一个数出现1次,其他数都出现了k次,请输出只出现了1次的数
思路:2个二进制数做不进位加法,结果为0,
k个k进制数做不进位加法,结果为0,
将数组中的数转换为k进制,进行不进位加法,结果保留的数再转换为10进制
public static void main(String[] args) {
int[] arr= {1, 1, 1, 3, 3, 3, 5, 6, 6, 6};
int len = arr.length;
char[][] kRadix = new char[len][];
int k=3;
int maxLen = 0;
//对每个数字,求每个数字的三进制字符串并翻转,数组的开头是低位,然后转为字符数组
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[] newArr = new int[maxLen];
//不进位加法,计算出每一列的和存储到newArr中
for(int i=0; i<len; i++) {
for(int j=0; j<maxLen; j++) {
if(j >= kRadix[i].length)
newArr[j]+=0;
else
newArr[j] += (kRadix[i][j] - '0'); //char转化为数字,即与‘0’的差距
}
}
int num=0;
//每一列取余,再转换为10进制数
for(int i=0; i<maxLen; i++) {
num += (newArr[i] % k) * (int)(Math.pow(k, i));
}
System.out.println(num);
}