update list&tree
This commit is contained in:
@@ -5,3 +5,35 @@
|
||||
|
||||
|
||||
|
||||
|
||||
```Java
|
||||
static AtomicInteger qpsCount = 100; //线程安全
|
||||
static volatile long lastSenconds = System.currentTimeMillis()/1000;
|
||||
|
||||
//1 计数器
|
||||
public static boolean tryAcquire() {
|
||||
|
||||
long current = System.currentTimeMillis()/1000;
|
||||
if(current == lastSenconds){
|
||||
|
||||
if (qpsCount-- > 0) {//CAS api
|
||||
return true;
|
||||
} else {
|
||||
//限流
|
||||
return false;
|
||||
}
|
||||
|
||||
} else{//下一个时间窗口
|
||||
lastSenconds = current;
|
||||
qpsCount = 100;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
数据结构
|
||||
|
||||
```
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
+89
-9
@@ -6,18 +6,18 @@
|
||||
特点
|
||||
|
||||
* 堆总是一颗完全二叉树树, 使用数组作为其存储结构,因此也叫 `二叉堆`; 用链表存的就叫二叉树了
|
||||
* 任一节点小于(或大于)其所有的孩子节点;
|
||||
* 任一节点小于(或大于)其所有的孩子节点;
|
||||
* 堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
|
||||
* 小根堆: 每次取出来的元素都是队列中值最小的
|
||||
|
||||
|
||||
堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
|
||||
|
||||
`堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。
|
||||
|
||||
比如大根堆存储示例
|
||||
|
||||
```
|
||||
10, 7, 6 , 3, 4, 1, 5
|
||||
```
|
||||
比如小根堆存储示例
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 应用场景
|
||||
@@ -28,6 +28,88 @@
|
||||
|
||||
|
||||
|
||||
### Java PriorityQueue
|
||||
|
||||
|
||||
Java PriorityQueue 类就是 通过二叉小顶堆实现 ,也叫优先级队列实现。 有如下特点:
|
||||
|
||||
* 实现 Queue 接口
|
||||
* 头部是基于自然排序或基于比较器的排序的最小元素
|
||||
* 不是线程安全的,PriorityBlockingQueue在并发环境中使用
|
||||
|
||||
|
||||
|
||||
API 如下:
|
||||
|
||||
* boolean add(object):将指定的元素插入此优先级队列。
|
||||
* boolean offer(object):将指定的元素插入此优先级队列。
|
||||
* boolean remove(object):从此队列中删除指定元素的单个实例(如果存在)。
|
||||
* Object poll():检索并删除此队列的*头部*,如果此队列为空,则返回null。
|
||||
* Object element():检索但不删除此队列的*头部*,如果此队列为空,则返回null。
|
||||
* Object peek():检索但不删除此队列的*头部*,如果此队列为空,则返回null。
|
||||
* void clear():从此优先级队列中删除所有元素。
|
||||
|
||||
|
||||
```
|
||||
{
|
||||
PriorityQueue<Employee> pq = new PriorityQueue();
|
||||
pq.add(new Employee(1L, "AAA", LocalDate.now()));
|
||||
pq.add(new Employee(4L, "BBB", LocalDate.now()));
|
||||
pq.add(new Employee(3L, "DDD", LocalDate.now()));
|
||||
pq.add(new Employee(7L, "GGG", LocalDate.now()));
|
||||
pq.add(new Employee(2L, "CCC", LocalDate.now()));
|
||||
|
||||
while (true) {
|
||||
Employee head = pq.poll();
|
||||
System.out.println(head);
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
输出
|
||||
|
||||
```
|
||||
Employee [id=1, name=AAA, dob=2021-12-22]
|
||||
Employee [id=2, name=CCC, dob=2021-12-22]
|
||||
Employee [id=3, name=DDD, dob=2021-12-22]
|
||||
Employee [id=4, name=BBB, dob=2021-12-22]
|
||||
Employee [id=7, name=GGG, dob=2021-12-22]
|
||||
```
|
||||
|
||||
|
||||
如下,使用 PriorityQueue实现的 top-K 大问题,实现如下:
|
||||
|
||||
```Java
|
||||
/**
|
||||
* 小根堆实现
|
||||
*/
|
||||
public static int findMaxK(int[] nums, int k) {
|
||||
PriorityQueue<Integer> pq = new PriorityQueue<>(k, (a, b) -> (a-b) );
|
||||
|
||||
for (int i = 0; i <nums.length ; i++) {
|
||||
//取出前k个元素放入 PQ 中
|
||||
if (i < k) {
|
||||
pq.add(nums[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer head = pq.peek();
|
||||
if (head < nums[i]) {//维护 priorityQueue 中元素只有k个
|
||||
pq.poll();
|
||||
pq.add(nums[i]);
|
||||
}
|
||||
}
|
||||
return pq.poll();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
# 堆存储结构
|
||||
|
||||
|
||||
@@ -47,8 +129,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
优先级队列的代码实现
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
* 字符串的排列和组合
|
||||
|
||||
|
||||
## Java 字符串处理 常用 API
|
||||
|
||||
```
|
||||
String
|
||||
charAt(index)
|
||||
char[]
|
||||
Map<Character,Integer>
|
||||
```
|
||||
|
||||
|
||||
## 判断字符串是否是回文
|
||||
|
||||
@@ -27,11 +27,14 @@ char char_first_appear_once(const unsigned char *source){
|
||||
int hash[256]={0};
|
||||
char *tmp = source;
|
||||
if (tmp == NULL) return '\0';
|
||||
|
||||
//第一次建立hash表 key为字符,value为出现次数
|
||||
while(*tmp != '\0'){
|
||||
hash[*tmp]++;
|
||||
tmp++;
|
||||
}
|
||||
|
||||
//第二次扫描找到第一个value为1的key
|
||||
tmp = source;
|
||||
while(*tmp != '\0'){
|
||||
if (hash[*tmp] == 1) return *tmp;
|
||||
@@ -151,30 +154,6 @@ int lengthOfLongestSubstring(string s) {
|
||||
|
||||
|
||||
|
||||
|
||||
## 最长公共子串问题
|
||||
|
||||
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
|
||||
|
||||
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。
|
||||
|
||||
```
|
||||
int longest_common_subsequence(const char *s1,const char *s2, char *common)
|
||||
```
|
||||
|
||||
分析:求最长公共子串(Longest Common Subsequence,LCS)是一道非常经典的动态规划题,因此一些重视算法的公司像MicroStrategy都把它当作面试题。如"abccade","dgcadde"的最大子串为"cad"
|
||||
|
||||
|
||||
|
||||
实例代码:
|
||||
|
||||
```
|
||||
int longest_common_subsequence(const char *s1,const char *s2, char *common){
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 对称子字符串的最大长度 (最长回文子串)
|
||||
|
||||
题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
|
||||
@@ -228,6 +207,40 @@ int max_symmetrical_char_length(const char *scr){
|
||||
```
|
||||
|
||||
|
||||
## 最小覆盖子串
|
||||
|
||||
(难度 hard) `滑动窗口`
|
||||
|
||||
给定 字符串 s, t ; 在字符串 s 里找出 包含 t 所有字母的最小子串
|
||||
eg: s = "ADOBECODEBANC" t = "ABC" 输出: "BANC"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 最长公共子串问题
|
||||
|
||||
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
|
||||
|
||||
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。
|
||||
|
||||
```
|
||||
int longest_common_subsequence(const char *s1,const char *s2, char *common)
|
||||
```
|
||||
|
||||
分析:求最长公共子串(Longest Common Subsequence,LCS)是一道非常经典的动态规划题,因此一些重视算法的公司像MicroStrategy都把它当作面试题。如"abccade","dgcadde"的最大子串为"cad"
|
||||
|
||||
|
||||
|
||||
实例代码:
|
||||
|
||||
```
|
||||
int longest_common_subsequence(const char *s1,const char *s2, char *common){
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 求最大连续递增数字子串
|
||||
|
||||
@@ -79,22 +79,6 @@ char *revert_by_word(char *source){
|
||||
用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。
|
||||
|
||||
|
||||
## 左旋转字符串
|
||||
|
||||
>字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
|
||||
|
||||
如把`字符串abcdef`左旋转2位得到`字符串cdefab` 。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。
|
||||
|
||||
```
|
||||
char *left_rotate(char *str,int offset){
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
思路: 我们可以abcdef分成两部分,ab和cdef,内部逆序以后,整体再次逆序,就可以得到想要的结果了。
|
||||
也就是跟上面的问题是同样的问题。
|
||||
|
||||
|
||||
|
||||
## 替换空格
|
||||
|
||||
@@ -138,6 +122,23 @@ char *replace_blank(char *source){
|
||||
```
|
||||
|
||||
|
||||
## 左旋转字符串
|
||||
|
||||
>字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
|
||||
|
||||
如把`字符串abcdef`左旋转2位得到`字符串cdefab` 。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。
|
||||
|
||||
```
|
||||
char *left_rotate(char *str,int offset){
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
思路: 我们可以abcdef分成两部分,ab和cdef,内部逆序以后,整体再次逆序,就可以得到想要的结果了。
|
||||
也就是跟上面的问题是同样的问题。
|
||||
|
||||
|
||||
|
||||
|
||||
## 字符串原地压缩
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
## 小写字母排在大写字母的前面
|
||||
|
||||
有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在大写字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型:
|
||||
|
||||
@@ -119,6 +119,32 @@ int topK(int * a, int length, int k)
|
||||
|
||||
|
||||
|
||||
```Java
|
||||
/**
|
||||
* 小根堆实现
|
||||
*/
|
||||
public static int findMaxK(int[] nums, int k) {
|
||||
PriorityQueue<Integer> pq = new PriorityQueue<>(k, (a, b) -> (a-b) );
|
||||
|
||||
for (int i = 0; i <nums.length ; i++) {
|
||||
//取出前k个元素放入 PQ 中
|
||||
if (i < k) {
|
||||
pq.add(nums[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer head = pq.peek();
|
||||
if (head < nums[i]) {//维护 priorityQueue 中元素只有k个
|
||||
pq.poll();
|
||||
pq.add(nums[i]);
|
||||
}
|
||||
}
|
||||
return pq.poll();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## 最长公共子序列 (动态规划的经典题目)
|
||||
|
||||
|
||||
@@ -196,6 +196,8 @@ static int partition(int[] nums, int left, int right){
|
||||
|
||||
### 滑动窗口
|
||||
|
||||
双指针中有一类比较难的技巧就是`滑动窗口`
|
||||
|
||||
滑动窗口: 无重复字符的最长子串
|
||||
|
||||
```Java
|
||||
@@ -205,6 +207,7 @@ public static int longestSubString(char[] s){
|
||||
int res = 0; // 记录最长结果
|
||||
|
||||
Map<Character, Integer> window = new HashMap<Character, Integer>();
|
||||
|
||||
while (right < s.length) {
|
||||
Character c = s[right];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user