选择排序
1 | public static void selectionSort(int[] arr) |
冒泡排序
1 | public static void bubbleSort(int[] arr) |
异或运算(^)
- 相同为0,不同为1
- 还可以理解成:无进位相加性质:
1
2
3
4
5
6
7
8
9
10a^b = 1
0^1 = 1
1^0 = 1
0^0 = 0
1^1 = 0
a: 10110
b: 00111
a^b:
100011
2
3
4
5
6
7
8
9
101.
0^N = N : 0跟任何数N异或,都是N
N^N = 0 : 任何数跟自己异或,都得0
2.
满足交换律、结合律
a^b = b^a
(a^b)^c = a^(b^c)
3.同一批数异或运算,谁先谁后的顺序不影响结果
1 | public static void swap(int[] arr, int i, int j) |
面试题:
- 在一个整形数组int[] arr中,
1)已知只有一种数出现了奇数次,其他的所有数都出现了偶数次
怎么找到出现了奇数次的数
2)已知有两种数出现了奇数次,其他的所有数都出现了偶数次
怎么找到这两种数
要求:时间复杂度O(N),额外空间复杂度O(1)
key:
1)
1 | int eor = 0; |
2)
1 | int eor = 0; |
插入排序
- 时间复杂度O(N^2),额外空间复杂度O(1)
- 插入排序在某些数据状况下并不是严格的O(N^2),会优于选择/冒泡排序
- 时间复杂度
O是按算法最差情况下的时间复杂度,
θ是平均状况下的时间复杂度,
Ω是最好情况下的时间复杂度,
后两个指标实际用处不大,可以不记,只用记O
1 | public static void insertionSort(int[] arr) |
二分法
- 在一个有序数组中,找某个数是否存在
- 遍历找一个数的方法,时间复杂度O(N)
- 二分法找,先找数组最中间的数,因为有序,所以可以砍掉一半,继续二分,时间复杂度O(log2^N),默认都写成log(N)
- 8个 4个 2个 1个 log2^8 = 砍3次
- 在一个有序数组中,找>=某个数最左侧的位置
- 做记号,二分到结束为止
- 局部最小值问题
- 数组无序,相邻数一定不相等