algorithm-linked-list
链表相关
翻转链表
12345678910ListNode reverseList(ListNode head) { ListNode pre = null, cur = head; while (cur != null) { ListNode next = cur.next; cur.next = pre; pre = cur; cur = next; } return pre;}
快慢指针找中间节点
12345678ListNode getMidNode(ListNode head) { ListNode fast = head, slow = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow;} ...
solution-clash-terminal-access-github
解决git终端访问github超时问题【clash】,通过给git设置代理解决
note-java
关于Java的一些笔记
tips-java
Java刷题技巧
数组相关操作
常见
1234567int arr[] = new int[size], n = arr.length; // 简化定义方式Arrays.equals(T[], T[]); // 比较System.arraycopy(src, 0, dst, 0, len); // 复制Arrays.copyOf(src, len); // 复制Arrays.copyOfRange(src, from, to); // 复制cnt[nxt] = cnt[cur].clone(); // 复制(克隆)
sort
12345Arrays.sort(T[], Comparator); int arr[][] = {{1, 3}, {3, 1}};Arrays.sort(arr, (a,b)->b[1]-a[1]);int arr2[] = {1,3,2};Arrays.sort(arr2, (a,b)->b-a); // 报错,当放入Comparator参数时, ...
algorithm-dijkstra
Dijkstra算法
概念
Dijkstra 算法是一个可以解决单一源点最短路径问题的经典算法,本质上是对广度优先搜索(BFS)的一个推广,只是把 BFS 维护的栈换成了优先队列。
Dijkstra算法成立的前提条件是不存在负权的边,这意味任何一条路径,从起点开始到路径中每个点的距离都是依次递增的。所以按照递增的顺序来依次计算出最短路径也就是Dijkstra算法了
每次循环都会增多一个保证已经找到最短路的点。
直观来说,如果我们已经求出了k个离源点距离最近的点,以及它们各自的距离,那么到源点距离第k+1近的点,它到源点的最短路径只能经过这前k个点——如果经过了其他点,那么这个其他点显然离源点更近,那这个点一定不是第k+1近了。既然只经过这前k个点,那么只用这前k个点放缩就可以找到那个最短路径了。再加上前k-1个点上一轮已经放缩过,所以每一轮只需要用新加入的节点进行放缩就行了。
无法处理有负边的图
举例:
graph LR
s --2--> u -- -3--> v
s --1--> v
第一次贪心得到的点的路径s->v不是最短路
拓展 ...
algorithm-topo-sort
拓扑排序
概念
拓扑排序是一种在有向图中对节点进行排序的算法,其中每个节点表示一个任务或事件,而有向边表示任务间的依赖关系。拓扑排序可以帮助我们找到一种满足依赖关系的节点排列顺序,从而确保所有依赖关系得到满足。
概述
拓扑排序通常用于解决有向无环图(DAG)中的任务调度、依赖分析、编译顺序等问题。在一个有向图中,每个节点代表一个任务,而有向边代表任务间的依赖关系。拓扑排序的目标是找到一种节点排列,使得每个节点都排在它的后继节点之前,从而满足所有的依赖关系。
基于BFS的拓扑排序算法步骤
初始化一个队列,将所有入度为 0 的节点入队。
当队列不为空时,执行以下操作:
从队列中弹出一个节点,将其添加到结果列表中。
遍历该节点的所有后继节点(邻居节点):
将后继节点的入度减一。
如果后继节点的入度变为 0,则将其入队。
重复步骤 2,直到队列为空。
基于DFS的拓扑排序算法步骤
选择一个没有入边的节点作为起点。
对起点节点进行DFS遍历,将遍历过程中的节点按照逆序加入到结果列表中。
重复步骤 1 和步骤 2,直到所有节点都被遍历过。
课程表
你这个学期必须选修 numC ...
algorithm-tree-segment-tree
线段树
概念
线段树是一种用于解决区间更新和区间查询问题的高效数据结构
这里我把区间更新分成两种(upd函数)
区间添加更新,给这个区间的子数组都添加上某个值
区间覆盖更新,把这个区间的子数组都赋值为某个值
而区间查询也大概分为两种(query函数)
区间和查询,求这个区间的数组的元素值之和
区间最大值查询,求这个区间的数组的元素值的最大值
数组无lazy线段树
模板:区间添加更新,区间和查询
12345678910111213141516171819202122232425262728293031323334353637383940414243444546class SegmentTree { int[] nums; int len; int[] tree; public SegmentTree(int[] nums) { this.nums = nums; this.len = nums.length; tree = new int[4 * len]; build(1 ...