diff --git a/2 List/QPS Counter.md b/2 List/QPS Counter.md index 3411dea..570c2c4 100644 --- a/2 List/QPS Counter.md +++ b/2 List/QPS Counter.md @@ -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; + } + } +``` + + + + + + + diff --git a/2 List/数组.md b/2 List/数组.md index 2be85e1..dc02027 100644 --- a/2 List/数组.md +++ b/2 List/数组.md @@ -18,7 +18,6 @@ - 数据结构 ``` diff --git a/4 Tree/8-堆/pq-1.png b/4 Tree/8-堆/pq-1.png new file mode 100644 index 0000000..78202ff Binary files /dev/null and b/4 Tree/8-堆/pq-1.png differ diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index 74111ad..c490690 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -6,18 +6,18 @@ 特点 * 堆总是一颗完全二叉树树, 使用数组作为其存储结构,因此也叫 `二叉堆`; 用链表存的就叫二叉树了 -* 任一节点小于(或大于)其所有的孩子节点; +* 任一节点小于(或大于)其所有的孩子节点; +* 堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 +* 小根堆: 每次取出来的元素都是队列中值最小的 -堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 - `堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。 -比如大根堆存储示例 -``` -10, 7, 6 , 3, 4, 1, 5 -``` +比如小根堆存储示例 + +![小根堆](./pq-1.png) + ### 应用场景 @@ -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 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 pq = new PriorityQueue<>(k, (a, b) -> (a-b) ); + + for (int i = 0; i +``` ## 判断字符串是否是回文 diff --git a/9 Algorithms Job Interview/1.1 字符串-查找.md b/9 Algorithms Job Interview/1.1 字符串-查找.md index 7618a01..dc80de2 100644 --- a/9 Algorithms Job Interview/1.1 字符串-查找.md +++ b/9 Algorithms Job Interview/1.1 字符串-查找.md @@ -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){ + +} +``` + ## 求最大连续递增数字子串 diff --git a/9 Algorithms Job Interview/1.3 字符串-修改.md b/9 Algorithms Job Interview/1.3 字符串-修改.md index 4b18a11..0fcf775 100644 --- a/9 Algorithms Job Interview/1.3 字符串-修改.md +++ b/9 Algorithms Job Interview/1.3 字符串-修改.md @@ -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,内部逆序以后,整体再次逆序,就可以得到想要的结果了。 +也就是跟上面的问题是同样的问题。 + + + ## 字符串原地压缩 diff --git a/9 Algorithms Job Interview/1.4 字符串-排序.md b/9 Algorithms Job Interview/1.4 字符串-排序.md index 9dd1338..9bc9900 100644 --- a/9 Algorithms Job Interview/1.4 字符串-排序.md +++ b/9 Algorithms Job Interview/1.4 字符串-排序.md @@ -2,7 +2,6 @@ - ## 小写字母排在大写字母的前面 有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在大写字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型: diff --git a/9 Algorithms Job Interview/5.4 数列-查找.md b/9 Algorithms Job Interview/5.4 数列-查找.md index ac9bd9b..24cf68b 100644 --- a/9 Algorithms Job Interview/5.4 数列-查找.md +++ b/9 Algorithms Job Interview/5.4 数列-查找.md @@ -119,6 +119,32 @@ int topK(int * a, int length, int k) +```Java +/** + * 小根堆实现 + */ + public static int findMaxK(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>(k, (a, b) -> (a-b) ); + + for (int i = 0; i window = new HashMap(); + while (right < s.length) { Character c = s[right];