参考视频:一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解(马士兵) 点击观看
文章目录
选择排序
java
public class Main {
public static void main(String[] args) {
//选择排序
int[] a = {5, 4, 3, 2, 1};
for (int i = 0; i < a.length; i++) {
int min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[j] < a[min]) {
min = j;
}
}
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
}
冒泡排序
java
public class Main {
public static void main(String[] args) {
//冒泡排序
int[] arr = {1, 5, 3, 2, 4};
for (int i = arr.length - 1; i > 0 ; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int k = 0; k < arr.length; k++) {
System.out.print(arr[k] + " ");
}
}
}
异或运算
0^n=n和n^n=0- 满足交换律和结合律:
a^b=b^a和(a^b)^c=a^(b^c) - 一堆数字统一异或在一起形成一个数的值与这一堆数字选择谁先异或谁后异或的顺序没有关系。
swap
java
public class Main {
public static void main(String[] args) {
//交换两个数使用中间变量
int a = 1;
int b = 2;
int temp = a;
a = b;
b = temp;
System.out.println(a);
System.out.println(b);
System.out.println("---");
//交换两个数使用异或
int a1 = 3;
int b1 = 4;
a1 = a1 ^ b1;
b1 = a1 ^ b1;
a1 = a1 ^ b1;
System.out.println(a1);
System.out.println(b1);
}
}

注意: 不能交换指向同一内存地址的变量如果两个变量本质上是同一个内存地址(比如 swap(arr[i], arr[i]),或 a = b 指向同一引用),执行异或交换会导致变量值被清零。
题目
- 在一个数组中已知只有一种数出现了奇数次,其他的所有数都出现了偶数次,怎么找到出现了奇数次的数?
- 在这个数组中已知有两种数出现了奇数次,其他的所有数都出现了偶数次,怎么找到出现的这两种奇数次的数?
- 要求时间复杂度为O(n),空间复杂度为O(1)


java
public class Main {
public static void main(String[] args) {
//在一个数组中已知只有一种数出现了奇数次,其他的所有数都出现了偶数次,怎么找到出现了奇数次的数?
int[] arr = {1, 2, 3, 2, 1, 4, 4, 4, 4};
System.out.println(findOddNum(arr));
}
public static int findOddNum(int[] arr) {
int res = 0;
for (int i = 0; i < arr.length; i++) {
res ^= arr[i];
}
return res;
}
}




int rightOne = eor & (~eor + 1);//获取一个非零数的最右侧的1
java
public class Main {
public static void main(String[] args) {
int[] arr = {2, 2, 3, 4, 4, 6, 7, 7, 9, 9};
singleNumber(arr);
}
public static void singleNumber(int[] nums) {
int eor = 0;
for (int i = 0; i < nums.length; i++) {
eor ^= nums[i];
}
//eor = a^b
//eor != 0
//eor一定有一个位置上是1
int rightOne = eor & (~eor + 1);//获取eor最右侧的1
int onlyOne = 0;//eor'
for (int i = 0; i < nums.length; i++) {
//选择一边
if ((nums[i] & rightOne) != 0) {
onlyOne ^= nums[i];
}
}
System.out.println(onlyOne);//a或者b
System.out.println(eor ^ onlyOne);
}
}
插入排序
java
public class Main {
public static void main(String[] args) {
//插入排序
int[] arr = {5, 4, 3, 2, 1};
//0~0有序
for (int i = 1; i < arr.length; i++){//0~i做到有序
for(int j = i-1; j >= 0 && arr[j] > arr[j+1]; j--){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
二分
在一个有序 数组中,找某个数是否存在。
时间复杂度:O(log2N)
在一个有序数组中,找到>=某个数最左侧的位置。