LeetCode 代码模板Java版

二分查找

排序的写法

在这里插入图片描述
算法复杂度:
在这里插入图片描述

快速排序

private static int[] quickSort(int arr[], int left, int right) {
        if (right <= left) {
            return;
        }
        int base = partition(arr, left, right);
        quickSort(arr, left, base - 1);
        quickSort(arr, base + 1, right);
        return arr;
}

private static int partition(int[] arr, int low, int high) {
    int base = arr[low];
    while (low < high) {
        while (low < high && arr[high] >= base){
            high--;
        }
        arr[low] = arr[high];
        while (low < high && arr[low] <= base){
            low++;
        }
        arr[high] = arr[low];
    }
    arr[low] = base;
    return low;
}

归并排序

 //将有二个有序数列a[first...mid]和a[mid...last]合并。
 private static void mergearray(int[] arr, int left, int mid, int right) {
     int i = left, j = mid + 1, k = 0;
     int temp[] = new int[right - left + 1];
     while (i <= mid && j <= right) {
         temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
     }

     while (i <= mid)
         temp[k++] = arr[i++];

     while (j <= right)
         temp[k++] = arr[j++];

     for (int p = 0; p < k; p++) {
         arr[left + p] = temp[p];
     }
 }
public static void mergesort(int a[], int left, int right) {
    if (right <= left) {
        return;
    }
    int mid = (left + right) >> 1; // (left + right) / 2
    mergesort(a, left, mid);    //左边有序
    mergesort(a, mid + 1, right); //右边有序
    mergearray(a, left, mid, right); //再将二个有序数列合并
}

BFS的写法

public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> allResults = new ArrayList<>();
        if (root == null) {
            return allResults;
        }
        Queue<TreeNode> nodes = new LinkedList<>();
        nodes.add(root);
        while (!nodes.isEmpty()) {
            int size = nodes.size();
            List<Integer> results = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = nodes.poll();
                results.add(node.val);
                if (node.left != null) {
                    nodes.add(node.left);
                }
                if (node.right != null) {
                    nodes.add(node.right);
                }
            }
            allResults.add(results);
        }
        return allResults;
    }

DFS的写法

dfs 栈实现

    public static void dfs(TreeNode root){
        Stack<TreeNode> stack = new Stack<TreeNode>(); //借助stack
        if(root == null)
            return;
        stack.push(root);
        while(!stack.isEmpty()){ //若栈非空
            TreeNode node = stack.pop();
            System.out.print(node.val + " ");
            if(node.right != null) //先将右孩子结点压入堆栈
                stack.push(node.right);
            if(node.left != null) //然后将左孩子结点压入堆栈
                stack.push(node.left);
        }
    }

递归实现

public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> allResults = new ArrayList<>();
        if (root == null) {
            return allResults;
        }
        travel(root, 0, allResults);
        return allResults;
}

private void travel(TreeNode root, int level, List<List<Integer>> results) {
    if (results.size() == level) {
        results.add(new ArrayList<>());
    }
    results.get(level).add(root.val);
    if (root.left != null) {
        travel(root.left, level + 1, results);
    }
    if (root.right != null) {
        travel(root.right, level + 1, results);
    }
}

回溯法

递归

迭代

前序遍历

 private void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        pre.add(root.val);
        preOrder(root.left);
        preOrder(root.right);
}

中序遍历

private void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        in.add(root.val);
        inOrder(root.right);
}

后序遍历

private void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        post.add(root.val);
}

构建完全二叉树

并查集

 /**
     * 并查集
     */
    class UnionFind {
        private int count = 0;
        private int[] parent;

        public UnionFind(int n) {
            count = n;
            parent = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }
        }

        public int find(int p) {
            while (p != parent[p]) {
                parent[p] = parent[parent[p]];
                p = parent[p];
            }
            return p;
        }

        public void union(int p, int q) {
            int rootP = find(p);
            int rootQ = find(q);
            if (rootP == rootQ) {
                return;
            }
            parent[rootP] = rootQ;
            count--;
        }
    }

前缀树

图遍历

Dijkstra算法

Floyd-Warshall算法

Bellman-Ford算法

最小生成树

Kruskal算法

Prim算法

拓扑排序

双指针

动态规划

function DP(){
	dp = [][]
	for (int i = 0,i < N;i++){
		for (int j = 0,j < M;j++){
			dp[i][j] = _Function(dp[i`][j`])
		}	
	}
	return dp[M][N]
}

斐波那契数列
爬楼梯
换零钱
打家劫舍
股票买卖

状态搜索

贪心

AVL

平衡因子: 某个结点的左子树的高度减去右子树的高度得到的差值。[-1,0,1]由高度来决定查找速度

左旋:右右子树。抛弃左孩子,将之和旋转后的节点A 相连,成为节点 A的右孩子。
右旋:左左子树。抛弃右孩子,将之和旋转后的节点 C 相连,成为节点 C 的左孩子。

左右旋:先左旋,变成左左子树
右左旋:先右旋,变成右右子树

在这里插入图片描述

红黑树

红黑树是一种近似平衡的二叉搜索树 (Binary Search Tree),它能够确保任何一个结点的左右子树的高度差小于两倍。具体来说,红黑树是满足如下条件的二叉搜索树:
•每个结点要么是红色,要么是黑色
•根结点是黑色
•每个叶结点 (NI结点,空结点) 是黑色的。
•不能有相邻接的两个红色结点
•从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

在这里插入图片描述

位运算

判断奇偶性:x&1 == 1 x&1 == 0
除2:x >> 1
清零最低位的1:x&(x-1)
得到最低位的1:x&-x
得到0:x&~x

LRU(最近最少使用)

LinkedHashMap实现:

class LRUCache extends LinkedHashMap<Integer, Integer>{
    private int capacity;
    
    public LRUCache(int capacity) {
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    public int get(int key) {
        return super.getOrDefault(key, -1);
    }

    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity; 
    }
}

双向链表实现:

public class LRUCache {
    class Node {
        Node pre;
        Node next;
        int key;
        int value;

        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    class DoubleList {
        Node head = new Node(-1, -1);
        Node tail = new Node(-1, -1);
        int size;

        public DoubleList() {
            this.head.next = tail;
            this.tail.next = head;
            this.size = 0;
        }

        public void addFirst(Node n) {
            Node next = head.next;
            // 把n放到head 和next之间
            head.next = n;
            next.pre = n;

            n.pre = head;
            n.next = next;

            size++;
        }

        // 1-2-3 变为1-3
        public void remove(Node n) {
            n.pre.next = n.next;
            n.next.pre = n.pre;
            size--;
        }

        public Node removeList() {
            Node last = tail.pre;
            remove(last);
            return last;
        }

        public int size() {
            return size;
        }
    }

    private Map<Integer, Node> map;
    private DoubleList cache;
    private int capacity;


    public LRUCache2(int capacity) {
        this.capacity = capacity;
        map = new HashMap<>(capacity);
        cache = new DoubleList();
    }

    public int get(int key) {
        // key 不存在
        if (!map.containsKey(key)) {
            return -1;
        }
        // 删除列表中的节点
        Node node = map.get(key);
        cache.remove(node);
        // 添加节点到链表头部
        cache.addFirst(node);
        return node.value;
    }

    void put(int key, int value) {
        Node node = new Node(key, value);
        if (map.containsKey(key)) {// map 已存在,先删除cache里的
            cache.remove(map.get(key));
        } else if (cache.size() == capacity) {// cache 已满,淘汰最后一个
            // 删除链表最后一个
            Node remove = cache.removeList();
            // 删除map中的映射
            map.remove(remove.key);
        }
        // 放入新节点到map中
        map.put(key, node);
        // 添加新节点到头部
        cache.addFirst(node);
    }

    public static void main(String[] args) {
        LRUCache lruCache = new LRUCache(2);
//        lRUCache.put(1, 1); // 缓存是 {1=1}
//        lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
//        lRUCache.get(1);    // 返回 1
//        lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
//        lRUCache.get(2);    // 返回 -1 (未找到)
//        lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
//        lRUCache.get(1);    // 返回 -1 (未找到)
//        lRUCache.get(3);    // 返回 3
//        lRUCache.get(4);    // 返回 4
        lruCache.put(1, 1);
        lruCache.put(2, 2);
        int i1 = lruCache.get(1);
        System.out.println(i1);
        lruCache.put(3, 3);
        int i2 = lruCache.get(2);
        System.out.println(i2);
        lruCache.put(4, 4);
        int i3 = lruCache.get(1);
        System.out.println(i3);
        System.out.println(lruCache.get(3));
        System.out.println(lruCache.get(4));
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值