面经-算法

动态规划

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shenyang1026

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值