相同为0, 不同为 1
a^b
0 0 0
1 1 0
1 0 1
0 1 0
a 1 0 1 1 0
b 0 0 1 1 1
^ 1 0 0 0 1
还可以理解为 无进位相加 1+1 =0 1+0=1 0+0=0
性质:
- 0^ N= N
- N^N=0
- 满足交换律 结合律
- a ^ b =b ^ a
- (a ^b ) ^ c= a ^ (b ^ c)
示例:
int a= 甲 int b= 乙
a = a ^ b —> a=甲 ^ 乙 b=乙
b = a ^ b —> b=甲 ^ 乙 ^ 乙 = 甲 a=甲 ^ 乙
a = a ^ b —> a=甲 ^ 乙 ^ 甲= 乙 b=甲
a= 乙 b=甲
前提: a 和 b 是 内存独立的区域
a指向的内存 和 b 指向的内存 是不同的
在数组中, 使用 ^ 前提 是 i 位置不能等于 j位置
位与( & )
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001
第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0
位或( | )
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111
第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0
在一个整形数组中,
1.已知 只有 一种数 出现了 奇数次 ,其他的 所有数都出现了 偶数次
如何找到 出现了 奇数次的数
2.已知 有两种数 出现了 奇数次 ,其他的数 都出现了 偶数次
时间复杂度 o(n) 空间复杂度 o (1)
解题1: int eor=0;
arr【2,3,1,2,1,3,3,1,1】
eor 分别 与 数组的每个数 使用 ^
由于 2为偶数 2个 最终为 0
由于 1为偶数 4个 最终为 0
由于 3为奇数3个 最终为 3
而 0 ^ 甲 = 甲
题解2:
一个数 提反 该数+1 提取出最右侧的 1
int rightOne= eor & (~eor +1) // 提取出最右侧的1
eor = 1 0 1 0 1 1 1 1 0 0
~eor= 0 1 0 1 0 0 0 0 1 1
~eor+1= 0 1 0 1 0 0 0 1 0 0
eor& (~eor+1) =
0 0 0 0 0 0 0 1 0 0
选择排序 进行 0-i次排序 每次 0-i的地方保持顺序
package com.ma.zuoSuanFa;
/*
在一个整形数组中,
1.已知 只有 一种数 出现了 奇数次 ,其他的 所有数都出现了 偶数次
如何找到 出现了 奇数次的数
2.已知 有两种数 出现了 奇数次 ,其他的数 都出现了 偶数次
*/
public class CodeSeven {
public static void main(String[] args) {
CodeSeven codeSeven=new CodeSeven();
int[] s={2,3,1,2,1,3,3,1,1};
codeSeven.getOneJi(s);
int[] d={1,1,1,1,2,2,3,3,3,5,5,5};
codeSeven.getTwo(d);
codeSeven.fastsory(s);
}
private int[] fastsory(int[] d) {
//首先进行 0-i次做到有序
for (int i = 1; i < d.length; i++) {
//0-0有序 0-i想有序
for (int j=i-1 ; j>=0 && d[j] > d[j+1] ; j--){
swapD(d,j,j+1);
}
}
return d;
}
private void swapD(int[] d, int j, int i) {
int n=d[j];
d[j]=d[i];
d[i]=n;
}
private void getTwo(int[] d) {
//先求出eor=a ^ b
int eor=0;
for (int cur : d) {
eor ^=cur;
}
//eor=a ^ b
//eor !=0
//eor 必然有一个位置上 是 1
int rightOne= (eor) & (~eor +1);//求出最右侧的1
int onlyOne=0;
for (int cur : d) {
if ( (rightOne & cur )==0 )
{
onlyOne ^=cur;
}
}
System.out.println(onlyOne +" "+ (eor^onlyOne) );
}
/*
解题1: int eor=0;
arr【2,3,1,2,1,3,3,1,1】
eor 分别 与 数组的每个数 使用 ^
由于 2为偶数 2个 最终为 0
由于 1为偶数 4个 最终为 0
由于 3为奇数3个 最终为 3
而 0 ^ 甲 = 甲
*/
private int getOneJi(int[] s) {
int eor=0;
for (int i = 0; i <s.length ; i++) {
eor=eor ^ s[i];
}
return eor;
}
}
归并排序
package zuoSuanFa;
/*
归并排序
*/
public class MegreTest {
public static void main(String[] args) {
MegreTest megreTest=new MegreTest();
int[] arr={10,2,3,1,3,5,7,9,7,8,6};
megreTest.process(arr,0,arr.length-1);
}
private void process(int[] arr, int L, int R) {
if (L==R){
return;
}
int mid = (R-L)/2 + L;
process(arr,L,mid);
process(arr,mid+1,R);
merge(arr, L, mid, R);
}
private int[] merge(int[] arr, int L, int mid, int R) {
int[] help=new int[R-L +1];
int i=0;
int p1=L;
int p2=mid+1;
while (p1 <= mid && p2 <= R )
{
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++] ;
}
while (p1 <= mid){
help[i++] =arr[p1++];
}
while (p2 <= R)
{
help[i++]=arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L+i] = help[i];
}
return arr;
}
}