二分查找
在已有序的序列中按值,与数组mid位置的数比较
package com.algorithm;
public class BSExist {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9};
boolean isExist = exist(arr,10);
System.out.println(isExist);
}
public static boolean exist(int[] sortedArr, int num) {
if (sortedArr == null || sortedArr.length == 0) {
return false;
}
int left = 0;
int right = sortedArr.length - 1;
int mid = 0;
while (left < right) {
mid = left + ((right - left) >> 1);//mid=(left+right)/2,位运算N*2+1可以写成(N<<1)|1左移一位再或1
if (sortedArr[mid] == num) {
return true;
} else if (sortedArr[mid] > num) {
right = mid - 1;//去mid左边找
} else {
left = mid + 1;//去右边查找
}
}
return sortedArr[mid] == num;
}
}
异或运算
相同为0,相异为1.(位运算时,简记为无进位的相加,偶数个1为0,奇数个1为1)
1、swap方法的异或写法
//交换的异或写法(前提i不等于j,内存空间不同)
static void swap(int[] arr, int i, int j) {//a=甲,b=乙
arr[i] = arr[i] ^ arr[j];//a=甲^乙,b=乙
arr[j] = arr[i] ^ arr[j];//a=甲^乙,b=甲^乙^乙=甲
arr[i] = arr[i] ^ arr[j];//a=甲^乙^甲=乙,b=甲
}
2、一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
//arr中,只有一种数,出现奇数次
public static void printOddTimeNum1(int[] arr) {
int eor = 0;//0与任何数异或,为原来的数
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.print(eor);
}
3、提取int整型的数的最右侧的1
N&(~N+1),既N与(N取反+1)
//数出int数中二进制1的个数
public static int bitCounts(int N) {
int count = 0;
//011011010000
//000000010000 rightOne
//011011000000 循环1次后
while (N != 0) {
int rightOne = N & ((~N) + 1);//提取出最右侧的1
count++;
N ^= rightOne;//抹掉最右侧的1
}
return count;
}
4、一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
package com.algorithm;
public class EvenTimeOddTime {
public static void main(String[] args) {
int[] arr = {1, 1, 2, 2, 3, 3, 3, 4, 4, 4};
//printOddTimeNum1(arr);
printOddTimesNum2(arr);
}
//一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
//arr中,只有一种数,出现奇数次
public static void printOddTimeNum1(int[] arr) {
int eor = 0;//0与任何数异或,为原来的数
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.print(eor);
}
//提取int整型的数的最右侧的1
//N&(~N+1)N与(N取反+1)
//一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
//异或运算遍历数组,最后eor=a异或b,eor不等于0,说明a和b在(a异或b)的右侧的一个1上,一个为1,一个为0,
public static void printOddTimesNum2(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
//eor^=a^b
//eor!=0,eor必然有一个位置上时1
int rightOne = eor & (~eor + 1);//提取出最右的1,
// eor= 01100100
//rightOne = 00000100
int onlyOne = 0;//eor`,提取出最右侧1和(a异或b)最右侧也是1的那个数
for (int i = 0; i < arr.length; i++) {
if ((arr[i] & rightOne) != 0) {//只有在00000100上有1的那些数字异或到onlyOne中
onlyOne ^= arr[i];
}
}
System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
}