1、基础知识
时间复杂度
选择排序,冒泡排序时间复杂度O(n^2),空间复杂度O(1)。
等差数列
通项公式:an=a1+(n-1)d 。前n项和公式为:Sn=a1n+[n*(n-1)d]/2或Sn=[n(a1+an)]/2。
位运算
^ 异或运算:无进位相加
1、相同为0
2、不同为1
3、任何数与0异或为自己
4、自己与自己异或为0
5、满足交换律、结合律
异或运算例题:
public class findOddNum {
public static void main(String[] args) {
int[] arr1 = {1,1,2,3,3};
printOddTimesNum1(arr1);
int[] arr = {1,1,2,2,3,7,4,4,5,5};
printOddTimes2(arr);
}
public static void printOddTimesNum1(int[] arr) {
int ero = 0;
for (int j : arr) {
ero ^= j;
}
System.out.println(ero);
}
public static void printOddTimes2(int[] arr2) {
int ero = 0;
for (int i : arr2) {
ero ^= i;
}
//此时,ero = a^b, ero != 0
int eroRight = ero & (~ero + 1);//找到最右的1
int onlyOne = 0;
for (int cur : arr2) {
if ((cur & eroRight) == 0) {
onlyOne ^= cur;
}
}
System.out.println(onlyOne + "-" + (ero^onlyOne));
}
}
2、排序算法
选择排序
public class SelectionSort {
public static void main(String[] args) {
int[] arr = {1, 0, 3, 100, 2};
selectionSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {// i ~ n-1 上找最小值下标
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
冒泡排序
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {3,0,10,2};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
swap(arr,i,j);
}
}
}
}
public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}.
}
插入排序
public class insertSort {
public static void main(String[] args) {
int[] arr = {1,3,3,2,6,5};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void insertSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
for (int i = 1; i < arr.length; i++) {
for (int j = i -1; j >= 0 && arr[j] > arr[j + 1]; j--) {//0~i上有序
swap(arr, j, j + 1);
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
归并排序
//时间复杂度o(n*logn)、空间复杂度o(n )
public class MergeSort {
public static void main(String[] args) {
int[] arr = {3, 5, 1, 4};
mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void mergeSort(int[] arr) {
if (arr == null || arr.length <= 0) {
return;
}
process(arr, 0, arr.length - 1);
}
public static void process(int[] arr, int L, int R) {
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);
process(arr, L, mid);
process(arr, mid + 1, R);
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
while (p1 <= M && p2 <= R) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
//L-R上有序的数组help拷贝到arr
for (int i1 = 0; i1 < help.length; i1++) {
arr[L + i1] = help[i1];
}
}
}
快速排序
public class QuitSort {
public static void main(String[] args) {
int[] arr = {4 ,5, 1, 3, 2};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
public static void quickSort(int[] arr, int L, int R) {
if (L < R) {
// swap(arr, L + (int)(Math.random() * (R - L + 1)), R);
int[] p = partition(arr, L, R);
//p[0]等于区域的左边界, p[0] - 1小于区域的右边界
quickSort(arr, L, p[0] - 1);
//p[1]等于区域的右边界, p[1]-1大于区域的左边界
quickSort(arr, p[1] + 1, R);
}
}
//默认以arr[R]做划分 <p ==p >p
//返回等于区域 (左边界,右边界),所以返回一个长度为2的数组
public static int[] partition(int[] arr, int L, int R) {
int less = L - 1;//<区右边界
int more = R;//>区左边界
while (L < more) {//L表示当前数的位置, arr[R]为划分值
if (arr[L] < arr[R]) {//当前数小于划分组
swap(arr, ++less, L++);
} else if (arr[L] > arr[R]) {//当前数大于划分组
swap(arr, --more, L);
}else {
L++;
}
}
swap(arr, more, R);
return new int[]{ less + 1, more};
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
3、递归
查找。最大值
public class GetMax {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 10, 0};
int max = getMax(arr);
System.out.println(max);
}
public static int getMax(int[] arr) {
return process(arr,0, arr.length-1);
}
public static int process(int[] arr, int l, int r) {
if (l == r) {
return arr[l];
}
int mid = l + ((r - l) >> 1);
int leftMax = process(arr, l, mid);
int rightMax = process(arr, mid+1, r);
return Math.max(leftMax,rightMax);
}
}