add frm
This commit is contained in:
@@ -60,6 +60,7 @@ typedef struct Entry{
|
|||||||
应用场景
|
应用场景
|
||||||
|
|
||||||
* mysql B+树 叶子节点就使用 双向链表,方便 `age<10` 类似条件查询,或者 倒序查询 如 `order by desc` ,从后向前遍历数据
|
* mysql B+树 叶子节点就使用 双向链表,方便 `age<10` 类似条件查询,或者 倒序查询 如 `order by desc` ,从后向前遍历数据
|
||||||
|
* Java AQS 中的等待队列, 是一个双端 双向链表 的结构 (FIFO 结构)
|
||||||
|
|
||||||
|
|
||||||
## 循环链表
|
## 循环链表
|
||||||
@@ -78,3 +79,7 @@ typedef struct Entry{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,6 @@ void traverse(int[] arr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 链表遍历框架
|
# 链表遍历框架
|
||||||
void traverse(ListNode head) {
|
|
||||||
for (ListNode p = head; p != null; p = p.next) {
|
|
||||||
// 迭代访问 p.val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void traverse(ListNode head) {
|
void traverse(ListNode head) {
|
||||||
|
|
||||||
ListNode p = head;
|
ListNode p = head;
|
||||||
@@ -49,10 +43,10 @@ void traverse(ListNode head) {
|
|||||||
p = p.next
|
p = p.next
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 递归
|
### 递归
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
@@ -79,10 +73,36 @@ void traverse(TreeNode root) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
比如,二叉树的最近公共祖先
|
||||||
|
|
||||||
|
```Java
|
||||||
|
TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
|
||||||
|
// base case
|
||||||
|
if (root == null) return null;
|
||||||
|
if (root == p || root == q) return root;
|
||||||
|
|
||||||
|
TreeNode left = lowestCommonAncestor(root.left, p, q);
|
||||||
|
TreeNode right = lowestCommonAncestor(root.right, p, q);
|
||||||
|
// 情况 1 :p, q 在 root 为根的树中
|
||||||
|
if (left != null && right != null) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
// 情况 2 :p, q 不在 在 root 为根的树中
|
||||||
|
if (left == null && right == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 情况 3 : p, q 只有1个在root 为根的树中
|
||||||
|
return left == null ? right : left;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### 二分查找
|
### 二分查找
|
||||||
|
|
||||||
|
[查找算法](../7%20Search/README.md)
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
|
// 1, 2, 2, 2, 2, 3
|
||||||
public int bsearch(int[] nums, int target){
|
public int bsearch(int[] nums, int target){
|
||||||
|
|
||||||
if(nums == null) {
|
if(nums == null) {
|
||||||
@@ -90,16 +110,16 @@ public int bsearch(int[] nums, int target){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = nums.length;
|
int high = nums.length;// 注意
|
||||||
|
|
||||||
while(low < high){
|
while(low < high){
|
||||||
middle = (high + low ) / 2;
|
middle = (high + low ) / 2;
|
||||||
if(nums[middle] < target){
|
if(nums[middle] < target){
|
||||||
low = middle;
|
low = middle + 1;
|
||||||
} else if (nums[middle] == target) {
|
} else if (nums[middle] == target) {
|
||||||
high = middle;//
|
high = middle;//继续向左早
|
||||||
} else {
|
} else {
|
||||||
high = middle;
|
high = middle; // 注意 , 这里没有 -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +127,69 @@ public int bsearch(int[] nums, int target){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 快慢指针
|
||||||
|
|
||||||
|
如下判断链表是否有环
|
||||||
|
|
||||||
|
```
|
||||||
|
public static boolean hasCycle(LinkNode head) {
|
||||||
|
if(head == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkNode p = head, q = head;
|
||||||
|
while(p.next != null && p.next.next != null && q.next != null) {
|
||||||
|
p = p.next.next;
|
||||||
|
q = q.next;
|
||||||
|
if(p == q) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 左右指针
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### 滑动窗口
|
### 滑动窗口
|
||||||
|
|
||||||
|
滑动窗口: 无重复字符的最长子串
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
|
|
||||||
|
public static int longestSubString(char[] s){
|
||||||
|
int left = 0, right = 0;
|
||||||
|
int res = 0; // 记录最长结果
|
||||||
|
|
||||||
|
Map<Character, Integer> window = new HashMap<Character, Integer>();
|
||||||
|
while (right < s.length) {
|
||||||
|
Character c = s[right];
|
||||||
|
|
||||||
|
//窗口变大
|
||||||
|
right++;
|
||||||
|
window.put(c, window.getOrDefault(c, 0) + 1); //java写的麻烦,不一定记得这个api
|
||||||
|
|
||||||
|
if (window.get(c) > 1) {
|
||||||
|
//判断左侧窗口是否要收缩
|
||||||
|
char d = s[left];
|
||||||
|
|
||||||
|
left ++;
|
||||||
|
window.put(d, window.get(d)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在这里更新答案
|
||||||
|
res = res > (right-left) ? res: (right-left);
|
||||||
|
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -126,7 +204,7 @@ void quicksort(int[] nums, int left, int right){
|
|||||||
if (left<right){//加上这个,不然有死循环,造成堆栈溢出,这也是递归结束条件
|
if (left<right){//加上这个,不然有死循环,造成堆栈溢出,这也是递归结束条件
|
||||||
|
|
||||||
//前序遍历位置
|
//前序遍历位置
|
||||||
//使得局部有序,i作为分隔
|
//使得局部有序,i作为分隔, i 前面的元素 小于 i 后面的元素
|
||||||
int i = partion(a,left,right);
|
int i = partion(a,left,right);
|
||||||
|
|
||||||
quicksort(a,left,i-1);
|
quicksort(a,left,i-1);
|
||||||
|
|||||||
Reference in New Issue
Block a user