1. 复杂度
复杂度我们一般考虑的是最坏情况
我们对常数时间操作以及非常数时间操作的基本数量就是“Big O” 时间复杂度。
常数时间操作:例如数组寻址 >>带符号右移,>>> 不带符号右移。
非常数时间操作:
还有一点:
异或操作是无进位相加
额外空间复杂度:与空间无关,是自己在操作的时候额外开辟的内存。
常数项:一些细枝末节的问题,随机大样本可以去测试出来,直接跑!!!
最优解是 时间复杂度、额外空间复杂度、常数项的总和评价,其中,时间复杂度是核心,也是最重要的!!!
2. 对数器
对数器就是对我们的方法进行测试的工具。
3. 二分法
要求:
1、数据量大,且有序
2、注意边界条件
找指定的数字:
public static void main(String[] args) {
int[] b = {1, 8, 9, 3, 1, 8, 9, 3, 9, 6, 6};
int[] c = {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 19, 22, 46};
System.out.println(findOddNum(c, 7));
}
public static int findOddNum(int[] arr, int value) {
// 验证数据是否可靠
if (arr == null || arr.length == 0) {
return -1;
}
int L = 0;
int R = arr.length - 1;
int mid = 0;
int index = -1;
while (L <= R) {
mid = L + ((R - L) >> 1);
if (arr[mid] <= value) {
index = mid;
L = mid + 1;
} else {
R = mid - 1;
}
}
return index;
}
// 二分查找的递归实现(https://time.geekbang.org/column/article/42520)
public int bsearch(int[] a, int n, int val) {
return bsearchInternally(a, 0, n - 1, val);
}
private int bsearchInternally(int[] a, int low, int high, int value) {
if (low > high) return -1;
int mid = low + ((high - low) >> 1);
if (a[mid] == value) {
return mid;
} else if (a[mid] < value) {
return bsearchInternally(a, mid+1, high, value);
} else {
return bsearchInternally(a, low, mid-1, value);
}
}
二分法找最小值:
二分中出现重复数字的情况:
public int bsearch(int[] a, int n, int value) {
int low = 0;
int high = n - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (a[mid] > value) {
high = mid - 1;
} else if (a[mid] < value) {
low = mid + 1;
} else {
if ((mid == 0) || (a[mid - 1] != value)) return mid;
else high = mid - 1;
}
}
return -1;
}
4. 几种简单的排序算法
选择冒泡插入,插入最优
快排归并,快排分区分治很优秀
桶计数,划分区域在范围内排序,计数省去排序
选择排序法
选择排序就是遍历所有元素,选出最小的一个来排序。
冒泡排序
冒泡排序就是涉及到一个互换的操作,一直和身边的人比,把最大的排在最后的做法。
插入排序
从小范围的有序到大范围的有序。最后再到整体的有序。
思路: