总结
一、
1.1 选择排序
- 每次循环找出最小与之换位
- 时间 O(N^2) 空间O(1)
public static void sort(int[] arr){
if(arr == null||arr.length < 2){
return;
}
for(int i = 0;i < arr.length - 1;i++){
int index = i;
for(int j = i + 1;j < arr.length;j++){
if(arr[index] > arr[j]){
index = j;
}
}
swap(arr,index,i);
}
}
private static void swap(int[] arr, int i, int index) {
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
1.2 冒泡排序
- 相邻两个数比较 大的交换
- 时间O(N^2)空间O(0)
public static void sort(int[] arr){
if(arr == null||arr.length < 2){
return;
}
for(int i = arr.length - 1;i > 0;i--){
for(int j = 0;j < i;j++){
if(arr[j] > arr[j + 1]){
swap(arr,j,j + 1);
}
}
}
}
private static void swap(int[] arr, int i, int j) {
arr[j] = arr[j] ^ arr[i];
arr[i] = arr[j] ^ arr[i];
arr[j] = arr[j] ^ arr[i];
}
1.3 插入排序 时间【N^2】最优
- 每次循环与前面的数比 大则换位置
- 时间O(N^2)空间O(0)
- 它的最差排序 才是时间复杂度
public static void sort(int[] arr){
if(arr == null||arr.length < 2){
return;
}
for(int i = 1;i < arr.length;i++){
for(int j = i;j > 0&&arr[j] < arr[j - 1];j--){
swap(arr,j,j - 1);
}
}
}
private static void swap(int[] arr, int i, int j) {
arr[j] = arr[j] ^ arr[i];
arr[i] = arr[j] ^ arr[i];
arr[j] = arr[j] ^ arr[i];
}
1.4 二分法查找
1.4.1 二分法查找
- 每次去中间下标 如果等于返回 否之边界交换
- 时间O(log2 N)空间O(1)
public static int sel(int[] arr,int num){
if(arr == null||arr.length == 0){
return -1;
}
int start = 0;
int end = arr.length - 1;
while(start <= end){
int mid = start + ((end - start) >> 1);
if(arr[mid] == num){
return mid;
}else if(arr[mid] > num){
end = mid - 1;
}else {
start = mid + 1;
}
}
return -1;
}
1.4.2 用二分法查找找出大于等于 num 最左边的下标
- 在二分查找的基础上 添加一个局部变量存储最左边下标
public static int max(int[] arr,int num){
if(arr == null||arr.length == 0){
return -1;
}
int start = 0;
int end = arr.length - 1;
int index = -1;
while(start <= end){
int mid = start + ((end - start) >> 1);
if(arr[mid] >= num){
index = mid;
end = mid - 1;
}else {
start = mid + 1;
}
}
return index;
}
1.5 异或 两道面试题
1.5.1 找出数组中一个奇数次出现的数
public static int sel(int[] arr){
if(arr == null||arr.length == 0){
return -1;
}
int num = 0;
for(int i = 0;i < arr.length;i++){
num ^= arr[i];
}
return num;
}
1.5.2 找出数组中两个个奇数次出现的数
public static void selLian(int[] arr){
if(arr == null||arr.length == 0){
return;
}
int num_0 = 0;
for(int i = 0;i < arr.length;i++){
num_0 ^= arr[i];
}
int right = num_0 & (~num_0 + 1);
int num_1 = 0;
for(int i = 0;i < arr.length;i++){
if((right & arr[i]) == 0){
num_1 ^= arr[i];
}
}
System.out.println((num_0 ^ num_1) + ":" + num_1);
}
二、
2.1 递归求数组最大值
public static int max(int[] arr){
return max(arr,0,arr.length - 1);
}
public static int max(int[] arr,int l,int r){
if(l == r){
return arr[l];
}
int mid = l + ((r - l) >> 1);
int right = max(arr,l,mid);
int left = max(arr,mid + 1,r);
return Math.max(right,left);
}
2.2 归并排序
- 用分而治之递归 外排序
- 时间O(NlogN)空间O(N)
public static void sort(int[] arr){ if(arr == null|| arr.length < 2){ return; } sort(arr,0,arr.length - 1); } private static void sort(int[] arr, int l, int r) { if(l == r){ return; } int mid = l + ((r - l) >> 1); sort(arr,l,mid); sort(arr,mid + 1,r); merge(arr,l,mid,r); } private static void merge(int[] arr, int l, int mid, int r) { int[] help = new int[r - l + 1]; int i = 0; int p1 = l; int p2 = mid + 1; while(p1 <= mid&&p2 <= r){ help[i++] = arr[p1] <= arr[p2]?arr[p1++]: arr[p2++]; } while(p1 <= mid){ help[i++] = arr[p1++]; } while(p2 <= r){ help[i++] = arr[p2++]; } for(int a:help){ arr[l++] = a; } }
2.2.1 小和问题
public static int sort(int[] arr){ if(arr == null|| arr.length < 2){ return 0; } return sort(arr,0,arr.length - 1); } private static int sort(int[] arr, int l, int r) { if(l == r){ return 0; } int mid = l + ((r - l) >> 1); return sort(arr,l,mid) + sort(arr,mid + 1,r) + merge(arr,l,mid,r); } private static int merge(int[] arr, int l, int mid, int r) { int[] help = new int[r - l + 1]; int i = 0; int p1 = l; int p2 = mid + 1; int count = 0; while(p1 <= mid&&p2 <= r){ if(arr[p1] < arr[p2]){ count += (r - p2 + 1) * arr[p1]; help[i++] = arr[p1++]; }else { help[i++] = arr[p2++]; } } while(p1 <= mid){ help[i++] = arr[p1++]; } while(p2 <= r){ help[i++] = arr[p2++]; } for(int a:help){ arr[l++] = a; } return count; }
2.2.2 逆序对
public static void sort(int[] arr){ if(arr == null|| arr.length < 2){ return; } sort(arr,0,arr.length - 1); } private static void sort(int[] arr, int l, int r) { if(l == r){ return; } int mid = l + ((r - l) >> 1); sort(arr,l,mid); sort(arr,mid + 1,r); merge(arr,l,mid,r); } private static void merge(int[] arr, int l, int mid, int r) { int[] help = new int[r - l + 1]; int i = 0; int p1 = l; int p2 = mid + 1; while(p1 <= mid&&p2 <= r){ if(arr[p1] < arr[p2]){ for(int j = p2;j <= r;j++){ System.out.println(arr[p1] + ":" +arr[j]); } help[i++] = arr[p1++]; }else { help[i++] = arr[p2++]; } } while(p1 <= mid){ help[i++] = arr[p1++]; } while(p2 <= r){ help[i++] = arr[p2++]; } for(int a:help){ arr[l++] = a; } }
2.3 荷兰国旗
2.3.1 比num >=的放左边 <的放右边
public static void sort(int[] arr,int num){ if(arr == null||arr.length < 2){ return; } int index = -1; for(int i = 0;i < arr.length;i++){ if(arr[i] <= num){ swap(arr,++index,i); } } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
2.3.2 比num >的放左边 == 放中间<的放右边
public static void sort(int[] arr,int num){
if(arr == null||arr.length < 2){
return;
}
int start = -1;
int end = arr.length;
for(int i = 0;i < end;i++){
if(arr[i] < num){
swap(arr,++start,i);
}else if(arr[i] > num){
swap(arr,--end,i--);
}
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
2.4 快速排序
- 把最后一个数对比前面 分左中右 最后跟右边最后换
- 随机一个数 放在最后
- 时间O(N*logN)空间 O(logN)
public static void sort(int[] arr){
if(arr == null||arr.length < 2){
return;
}
sort(arr,0,arr.length - 1);
}
private static void sort(int[] arr, int l, int r) {
if(l < r){
swap(arr,l + (int)(Math.random() * (r - l + 1)),r);
int[] p = some(arr,l,r);
sort(arr,l,p[0]);
sort(arr,p[1],r);
}
}
private static int[] some(int[] arr, int l, int r) {
int start = l - 1;
int end = r;
while(l < end){
if(arr[l] < arr[r]){
swap(arr,++start,l++);
}else if(arr[l] > arr[r]){
swap(arr,--end,l);
}else{
l++;
}
}
swap(arr,end++,r);
return new int[]{start,end};
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}