This commit is contained in:
ranwenjie
2021-11-27 02:15:19 +08:00
parent 10184a3450
commit b0c67229b3
9 changed files with 160 additions and 102 deletions
+21 -12
View File
@@ -4,6 +4,7 @@
* 双向链表
* 双向循环链表
## 链表
### 应用场景
@@ -11,18 +12,6 @@
* [redis slowlog](Redis%20slowlog.md)
### 扩缩容
简单说下编程语言 java, golang中 LinkList的扩缩容的策略。
java 中扩容,每次扩容新增原先容量的 1/2
```
int newCapacity = oldCapacity + (oldCapacity >> 1);
```
这个就不介绍了。重点说下双向链表。
### 链表 VS 数组
特点
@@ -38,12 +27,27 @@ java 中扩容,每次扩容新增原先容量的 1/2
### 扩缩容
简单说下编程语言 java, golang中 LinkList的扩缩容的策略。
java 中扩容,每次扩容新增原先容量的 1/2
```
int newCapacity = oldCapacity + (oldCapacity >> 1);
```
这个就不介绍了。重点说下双向链表。
## 双向链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
双向链表克服了单链表中访问某个节点前驱节点(插入,删除操作时),只能从头遍历的问题。
缺点是: 多了1倍的额外的指针空间大小。
```
typedef int Value
typedef struct Entry{
@@ -53,6 +57,11 @@ typedef struct Entry{
```
应用场景
* mysql B+树 叶子节点就使用 双向链表,方便 `age<10` 类似条件查询,或者 倒序查询 如 `order by desc` ,从后向前遍历数据
## 循环链表
最后一个节点指针指向头节点的链表
+1 -1
View File
@@ -1,6 +1,6 @@
# 红黑树 (red-black tree)
红黑树(Red Black Tree) 是一种自平衡二叉查找树。一种特化的AVL树,在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 它可以在O(log n)时间内做查找,插入和删除。
红黑树(Red Black Tree) 是一种自平衡二叉查找树。一种特化的[AVL树](../3-平衡树AVL/README.md),在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 它可以在O(log n)时间内做查找,插入和删除。
它的每个结点都被“着色”为红色或者黑色,这些结点的颜色被用来检测树的平衡性。
+5 -3
View File
@@ -4,11 +4,13 @@
* 回文判断
* 字符(串)统计
* [子串查找](1.1%20字符串-查找.md)
* [字符串修改](1.3%20字符串-修改.md) 如单词反转/移动等
* [字符删除](1.2%20字符串-删除.md)
* 字符串的压缩
* 字符串的排列和组合
* [子串查找](1.1%20字符串-查找.md)
* [字符删除](1.2%20字符串-删除.md)
* [字符串修改](1.3%20字符串-修改.md) 如单词反转/移动等
## 判断字符串是否是回文
@@ -45,19 +45,6 @@ char char_first_appear_once(const unsigned char *source){
题目扩展:这里的字符换成整数,整数数量几十TB,海量数据处理,显然hash方法不可能,没有那么大得内容
## 请编写能直接实现strstr()函数功能的代码。
> strstr(str1,str2) 判断str2是否是str1的子串。
```
/*
@ret 有就返回第一次出现子串的地址,否则返回NULL
*/
char *strstr(const char *source, const char *target){
}
```
### 字符串中找出连续最长的数字子串
@@ -164,11 +151,6 @@ int lengthOfLongestSubstring(string s) {
## 求最大连续递增数字子串
如“ads3sl456789DF3456ld345AA”中的“456789”就是所求。这道题在上一道题目的基础上增加了数字要递增的条件。思路跟上面差不多,碰到不递增的数字就相当于第二个数字串了。
## 最长公共子串问题
@@ -247,6 +229,27 @@ int max_symmetrical_char_length(const char *scr){
## 求最大连续递增数字子串
如“ads3sl456789DF3456ld345AA”中的“456789”就是所求。这道题在上一道题目的基础上增加了数字要递增的条件。思路跟上面差不多,碰到不递增的数字就相当于第二个数字串了。
## 请编写能直接实现strstr()函数功能的代码。
> strstr(str1,str2) 判断str2是否是str1的子串。
```
/*
@ret 有就返回第一次出现子串的地址,否则返回NULL
*/
char *strstr(const char *source, const char *target){
}
```
## 子串匹配的个数
已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,如果没有返回0,有的话返回子字符串的个数。
+12 -1
View File
@@ -10,12 +10,14 @@
* 链表中是否有环
链表结点定义如下:
链表结点定义如下:
```
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
```
@@ -110,6 +112,15 @@ struct ComplexNode
请完成函数`ComplexNode* Clone(ComplexNode* pHead)`,以复制一个复杂链表。
这个题目难点在于:
@@ -25,8 +25,6 @@ void sort(int * a, int length)
`动态规划`
## 扑克牌的顺子
@@ -87,13 +87,38 @@ topMaxK(int *a,int length, int k);
## 找第k大的数
比如 1,2,3,4,5,6,7和8这8个数字,低3大的数字是 6
比如 `1,2,3,4,5,6,7,8 `这 8个数字,第3大的数字是 6
```
int topK(int * a, int length, int k)
```
```Java
//冒泡实现
public int findK(int[] nums, int k){
//base case
if (nums== null || nums.length < k) {
return -1;
}
for(int i=1; i<=k; i++){
for(int j=0; j<nums.length-i; j++) {
int next = j+1;
if(nums[j]> nums[next]){
int tmp = nums[j];
nums[j] = nums[next];
nums[next] = tmp;
}
}
}
return nums[nums.length-k];
}
```
## 最长公共子序列 (动态规划的经典题目)
+54 -51
View File
@@ -13,7 +13,7 @@
* 编程细节:多练习,总结
常用解题套路工具
## 常用解题套路工具
* 数组,字符串问题:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。
* 二叉树问题:递归
@@ -21,6 +21,59 @@
* [常见算法题目Java实现](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo)
## 刷题框架套路
遍历
```
# 数组遍历框架
void traverse(int[] arr) {
for (int i = 0; i < arr.length; i++) {
// 迭代访问 arr[i]
}
}
# 链表遍历框架
void traverse(ListNode head) {
for (ListNode p = head; p != null; p = p.next) {
// 迭代访问 p.val
}
}
```
递归
```
# 链表递归
void traverse(ListNode head) {
// 递归访问 head.val
traverse(head.next);
}
# 二叉树递归
void traverse(TreeNode root) {
traverse(root.left);
traverse(root.right);
}
# 多叉树递归
void traverse(TreeNode root) {
for (TreeNode child : root.children)
traverse(child);
}
# 图的递归:,用个布尔数组 visited 做标记就行了
```
## [字符串](1%20字符串.md)
计算机处理的数据除了数值,就是字符。字符处理的常见问题包括:
@@ -95,56 +148,6 @@
# 刷题框架套路
遍历
```
# 数组遍历框架
void traverse(int[] arr) {
for (int i = 0; i < arr.length; i++) {
// 迭代访问 arr[i]
}
}
# 链表遍历框架
void traverse(ListNode head) {
for (ListNode p = head; p != null; p = p.next) {
// 迭代访问 p.val
}
}
```
递归
```
# 链表递归
void traverse(ListNode head) {
// 递归访问 head.val
traverse(head.next);
}
# 二叉树递归
void traverse(TreeNode root) {
traverse(root.left);
traverse(root.right);
}
# 多叉树递归
void traverse(TreeNode root) {
for (TreeNode child : root.children)
traverse(child);
}
# 图的递归:,用个布尔数组 visited 做标记就行了
```
# 参考
+20 -13
View File
@@ -22,6 +22,10 @@
* 链表
* 双向链表
### [数组](2%20List/README.md)
* [数组数列问题](%20Algorithms%20Job%20Interview/5%20数组数列问题.md)
数组和链表结构是基础结构,散列表、栈、队列、堆、树、图等等各种数据结构都基于数组和链表结构实现。
### [队列](2%20Queue/README.md)
@@ -36,13 +40,13 @@
### [字符串算法](1%20String/README.md)
* 排序
* 查找
* 子串查找 [字符串常见题目参考这里](%20Algorithms%20Job%20Interview/1%20字符串.md)
* BF算法
* KMP算法
* BM算法
* 正则表达式
* 数据压缩
* 排序
### [树](4%20Tree/README.md)
@@ -92,22 +96,25 @@
### [查找算法](7%20Search/README.md)
* 顺序表查找:顺序查找
* 有序表查找:二分查找
* 哈希表: O(1) [hashtable实现参考这里](../3%20Hash%20Table/README.md)
* 有序表查找:二分查找
* 顺序表查找:顺序查找, 复杂度O(N)
* 分块查找: 块内无序,块之间有序;可以先二分查找定位到块,然后再到`块`中顺序查找
* 动态查找: 二叉排序树,AVL树,B- ,B+(这里之所以叫 `动态查找表`,是因为表结构是查找的过程中动态生成的)
* 哈希表: O(1)
## [算法设计思想](8%20Algorithms%20Analysis/README.md)
* 迭代法
* 穷举搜索法
* 递推法
* 动态规划
* 贪心算法
* 回溯
* 分治算法
* [递归](8%20Algorithms%20Analysis/递归.md)
* [分治算法](8%20Algorithms%20Analysis/分治算法.md)
* [动态规划](8%20Algorithms%20Analysis/动态规划.md)
* [回溯法](8%20Algorithms%20Analysis/回溯法.md)
* [迭代法](8%20Algorithms%20Analysis/迭代法.md)
* [穷举搜索法](8%20Algorithms%20Analysis/穷举搜索法.md)
* [贪心算法](8%20Algorithms%20Analysis/贪心算法.md)