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));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)