动态规划
LRU缓存实现
package com.sy.test;
import java.util.HashMap;
/**
* @author 沈洋 邮箱:1845973183@qq.com
* @create 2022/1/14-17:30
**/
public class LRUCache {
// 头节点
private Entry head;
private HashMap<String,Entry> map;
public LRUCache() {
head = new Entry();
map = new HashMap<>(cap);
}
public void put(String key,int value){
Entry newEntry = new Entry(key,value);
moveToHead(newEntry);
map.put(key,newEntry);
}
private void moveToHead(Entry entry){
entry.next = head.next;
if(head.next!=null){
head.next.pre = entry;
}
head.next = entry;
}
public Integer get(String key){
Entry entry = map.get(key);
if(entry!=null){
Entry pre = entry.pre;
Entry next = entry.next;
pre.next = next;
next = pre;
moveToHead(entry);
}
return entry==null?null: entry.value;
}
static class Entry{
public Entry(String key, int value) {
this.key = key;
this.value = value;
}
public Entry() {
}
private String key;
private int value;
private Entry pre;
private Entry next;
}
public static void main(String[] args) {
var cache = new LRUCache();
cache.put("1",1);
cache.put("2",2);
cache.put("3",3);
cache.get("2");
}
}
排序
选择排序
排序思路:每次找到最小的元素,再交换到最前面
时间复杂度:O(N^2)
空间复杂度:O(1)
public <T extends Comparable<T>> void xuanze(T[] arr){
for(int i = 0; i < arr.length; i++){
int minIndex = i;
for(int j = i;j<arr.length;j++){
if(arr[j].compareTo(arr[minIndex])<0){
minIndex = j;
}
}
if(minIndex != i){
T temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
System.out.println(Arrays.toString(arr));
}
插入排序
排序思路:类似于插入扑克牌,将数组分为两部分:已排序和未排序
每次将未排序的第一个元素,向前遍历找到应该存在的位置
时间复杂度:O(N^2)
空间复杂度:O(1)
public <T extends Comparable<T>> void insertSOrt(T[] arr){
for(int i = 1;i<arr.length;i++){
// 向前遍历
int index = i;
for(int j = i-1;j>=0;j--){
if(arr[j].compareTo(arr[index])<0){
break;
}else{
// swap
T temp = arr[index];
arr[index] = arr[j];
arr[j] = temp;
index = j;
}
}
}
System.out.println(Arrays.toString(arr));
}
冒泡排序
排序思路:每次比较左右两个元素,并进行交换,最后将最大值移动到最右侧
时间复杂度:O(N^2)
空间复杂度:O(1)
冒泡排序是稳定的,相同元素不会进行交换
public <T extends Comparable<T>> void maopao(T[] array){
for(int i = 0;i<array.length;i++){
// 每次把最大值移动到最后
for(int j = 0; j< array.length-i-1;j++){
// 判断是否需要替换位置
if(array[j].compareTo(array[j+1])>0){
// 交换
T temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
希尔排序
排序思路:插入排序的变种,主要是将数组元素根据步长进行分组
时间复杂度:
public <T extends Comparable<T>> void shellSort(T[] arr){
// 确定步长
int h = arr.length/2;
// 逐渐减小步长,直到步长为1
while(h>0){
// 找到待插入的元素
// 把待插入的元素插入到有序数列中
// 进行插入排序
for(int i = h; i < arr.length; i++){
int index = i;
for(int j = i-h;j>=0;j-=h){
if(arr[j].compareTo(arr[index])>0){
// 交换
T temp = arr[j];
arr[j] = arr[index];
arr[index] = temp;
index = j;
}else break;
}
}
// 减小步长
h = h>>2;
}
System.out.println(Arrays.toString(arr));
}
归并排序
排序思路:递归排序,进行分组,合并时创建一个新数组来保存合并后的结果
时间复杂度:O(nlogn)
空间复杂度:O(n)
public <T extends Comparable<T>> void mergeSort(T[] arr,Class<T> type){
mergeSort(arr,0,arr.length-1,type);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
public <T extends Comparable<T>> void mergeSort(T[] arr,int left,int right,Class<T> type){
if(left>=right){
return;
}
int mid = (left+right)/2;
mergeSort(arr,left,mid,type);
mergeSort(arr,mid+1,right,type);
merge(arr,left,mid,right,type);
}
public <T extends Comparable<T>> void merge(T[] arr, int left, int mid, int right, Class<T> type ){
int left1 = left, left2 = mid+1;
T[] temp = (T[]) Array.newInstance(type,right-left+1);
int index = 0;
while(left1<=mid&&left2<=right){
if(arr[left1].compareTo(arr[left2])<=0){
temp[index++] = arr[left1++];
}else temp[index++] = arr[left2++];
}
// 处理未完成的元素
if(left1<=mid){
while(left1<=mid){
temp[index++] = arr[left1++];
}
}else if(left2<=right){
while(left2<=right){
temp[index++] = arr[left2++];
}
}
index = 0;
// 将排序后的结果复制回去
for(int i = left;i <= right;i++,index++){
arr[i] = temp[index];
}
}
快速排序
排序思路:每次对一个元素定位,将其他元素放到它的左边和右边
public <T extends Comparable<T>> void quickSort(T[] arr){
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public <T extends Comparable<T>> void quickSort(T[] arr,int left,int right){
if(left >= right){
return;
}
int mid = partition(arr,left,right);
quickSort(arr,left,mid-1);
quickSort(arr,mid+1,right);
}
private <T extends Comparable<T>> int partition(T[] arr,int left,int right){
int target = left;
while(left!=right){
while(right>left&&arr[right].compareTo(arr[target])>=0){
right--;
}
while(left<right&&arr[left].compareTo(arr[target])<=0){
left++;
}
if(left<right){
T temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
T temp = arr[target];
arr[target] = arr[left];
arr[left] = temp;
return left;
}