时间复杂度
一个操作如果和样本的数量没有关系,每次都是固定时间内完成的操作叫做常数操作。 时间复杂度为一个算法流程中,常数操作数量的一个指标。在表达式。
1. 插入排序
在小量数据中很占优势。插入排序从当前位置和左边的书比较,除非比到头了(到达0位置上的数)或者左边的数比当前数小,停止比较。
4和4左边9比较,4比9小,交换位置。
5和左边9比较,5比9小,交换位置 , 5比4大,比较停止,继续下一步。
7和左边9比较,7比9小,交换位置 , 7比5大,比较停止,继续下一步
1和左边9比较,1比9小,交换位置 ,再向前一个比,1比7小,交换位置 ,再向前一个比,1比5小,交换位置 ,再向前一个比, 1比4小,交互位置,继续向前发现到头了,不比了。
4和左边9比较,4比9小,交换位置 ,再向前一个比,4比7小,交换位置 ,再向前一个比,4比5小,交换位置 ,再向前一个比,4和4相等,不比了。
3和左边9比较,3比9小,交换位置 ,再向前一个比,3比7小,交换位置 ,再向前一个比,3比5小,交换位置 ,再向前一个比, 3比4小,交互位置,
再向前一个比, 3比4小,继续向前个比发现到3比4小,不比了。
排序完毕。
public static void insertSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i ; j > 0; j--) {
if (arr [j] > arr[j - 1]) {
break;
}
arr[j] = arr[j] ^ arr[j - 1];
arr[j - 1] = arr[j] ^ arr[j - 1];
arr[j] = arr[j] ^ arr[j - 1];
}
}
}
2. 选择排序
从当前位置向后找,找到最小值,交换我现在的所在位置。
从当前位置向后找,找到最小值和当前位置交换。
从第二个位置向后找,找到最小值和第二个位置交换。
从第3个位置向后找,找到最小值和第三个位置交换。
从第4个位置向后找,找到最小值和第四个位置交换。
从第5个位置向后找,找到最小值和第5个位置交换。
从第6个位置向后找,找到最小值和第6个位置交换。
排序完成。
public static void chooseSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (arr[min] < arr[i]) {
arr[i] ^= arr[min];
arr[min] ^= arr[i];
arr[i] ^= arr[min];
}
}
}
3. 冒泡排序
冒泡排序是和他下一个位置比较,如果右面比左面大,交换位置。冒泡排序闭着眼睛都能写出来,就直接贴代码了,不贴图了。
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; i++) {
if (arr[j] < arr[i]) {
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
}
}
}
}
4. 二分法使用场景
- 在一个有序数组中,找到某个数是否存在。
- 在一个有序数组中,找到>= 某个数最左侧的位置。
- 局部最小值问题。
5. 异或运算性质与扩展
定义:
两个集合A, B 相交, 什么是 Exclusive-or:找到 exclusive => 对于 A 来说 exclusive 就是我有你没有的, A - (A U B), 在 PS4, 但是不在 xbox 的游戏对于 B 来说 exclusive 就是我有你没有的, B - (A U B), 在 xbox, 但是不在 PS4 的游戏2. 然后 or 开始运作了, 也就是上面的情况 1 或者 情况 2 都可以.
- 从计算上看 异或,可以把他当成不进位的相加
0 | 1 |
---|---|
1 | 0 |
1 | 1 |
- 0 ^ N = N N ^ N = 0
- 异或运算满足交换律和结合律
- 不同额外变量交互两个数。
- 一个数组中有一种数出现了奇数次,其他数出现了偶数次,怎么找到这个数。
static int findOddNum(int[] arr) {
int temp = 0;
for (int a : arr) {
temp ^= a;
}
return temp;
}
- 一个数组中有2种数出现了奇数次,其他数出现了偶数次,怎么找到这2个数。
static int[] findTwoOddNum(int[] arr) {
int temp = 0;
//两个出现偶数次的数异或值 a ^ b
for (int a : arr) {
temp ^= a;
}
//现在找到这两个数,由于这两个数不一样,肯定某一个或多位的数1个是0另一个是1
//那么就找到从右数第一位为1的结果。
int firstLocationOne = (~temp + 1) & temp;
int firstOdd = 0;
//把所有的与右位该值不为0的数做异或,就可以得到该位置为1的数,即b
for (int a : arr) {
if ((a & firstLocationOne) != 0) {
firstOdd ^= a;
}
}
//将b与 a ^b 异或的值做异或,就可以得到a了
return new int[] {firstOdd, firstOdd ^ temp};
}