系列文章目录和关于我

一丶[无重复字符的最长子串](3. 无重复字符的最长子串 - 力扣(Leetcode))

思路:

维护一个窗口,窗口中不存在重复的字符,窗口右边界从第一个字符移动到最后,使用一个变量记录窗口大小的最大值

那么问题就变成了:怎么确保窗口中不存在重复的字符,我们可以使用一个set,每次发现right位置的字符A重复后,就一直移动到之前A字符位置的下一个。比如 BACDHA,此时right位于第二个A,set中包含字符BACDH,为了维持不重复,我们要将左边界移动到第一个C的位置,while循环让left右移,并删除left位置的字符,直到第一个A被删除

继续思考下,其实没必要使用一个set,直接使用一个map即可,map需要记录字符和这个字符最近出现的位置,当前字符重复A的时候,就让left移动到A最近出现位置的前一个。比如BACDHA,此时right为A,map中记录了B->0,A->1等信息,我们只需要让left移动到1+1(A最近出现于下标1,left需要移动到2位置)然后再map中重新记录A->5即可

代码:

  1. public int lengthOfLongestSubstring(String s) {
  2. //空字符串
  3. if(s==null||s.length()==0){
  4. return 0 ;
  5. }
  6. //窗口大小 最大值
  7. int res = 0;
  8. int left = 0;
  9. int right = 0;
  10. int len = s.length();
  11. //key字符,value 这个字符最近在什么位置出现
  12. HashMap<Character,Integer> recentLocation = new HashMap<>();
  13. while(right<len){
  14. //当前子u发
  15. char curChar = s.charAt(right);
  16. //获取这个字符出现的位置
  17. Integer index = recentLocation.get(curChar);
  18. //如果不为null 说明这个字符曾经出现过 那么这时候需要 让left 移动
  19. if(index!=null){
  20. left = Math.max(index+1,left);
  21. }
  22. //记录下最近的位置
  23. recentLocation.put(curChar,right);
  24. right++;
  25. //窗口最大长度更新
  26. res = Math.max(res,right-left);
  27. }
  28. return res;
  29. }

二丶[最小覆盖子串](76. 最小覆盖子串 - 力扣(Leetcode))

思路:

使用一个Map表示当前滑动串口亏欠t中字符的数量, key 字符 value 当前窗口中亏欠的数目,亏欠的意思是当前窗口至少还需要多少个key的字符才满足t

当left小于right的时候,我们尽可能让left向右滑动,那么什么时候left可以向右滑昵?——当前left是一个t中根本不存在的字符,或者窗口中left位置的字符数量大于t中的数量(对应下面两图)(这其实是有贪心的思想在其中的,题目是找最短的,那么left越接近right 那么越短)并且亏欠map需要同时维护

然后我们需要移动right指针,同时维护亏欠map

那么什么时候窗口中满足要求包含了t中所有字符昵——亏欠map中不存在value大于0的entry,这时候我们需要更新最佳结果

并且找到一个答案之后,我们需要left向右移动一个位置,并维护亏欠map,比如s=ADOBECODEBANC,t=ABC我们第一次找到符合的结果是ADOBEC,这时候需要left向右,因为后面存在更优秀的答案。

代码:

  1. class Solution {
  2. public String minWindow(String s, String t) {
  3. //逆天用例
  4. if (s == null || s.length() == 0) {
  5. return null;
  6. }
  7. if(s.length() < t.length()){
  8. return "";
  9. }
  10. char[] tCharArray = t.toCharArray();
  11. // key 字符 value 当前窗口中亏欠的数目,亏欠的意思是当前窗口至少还需要多少个key的字符才满足t
  12. // value 为正数 表示窗口欠 t,0表示互不亏欠,负数表示窗口中此字符数目多于t
  13. Map<Character, Integer> owesCharCountMap = new HashMap<Character, Integer>();
  14. //初始化亏欠的数目
  15. for (char loop : tCharArray) {
  16. owesCharCountMap.put(loop, owesCharCountMap.getOrDefault(loop, 0) + 1);
  17. }
  18. String res = null;
  19. int left = 0;
  20. int right = 0;
  21. while (right < s.length()) {
  22. //如果left对应字符是无关紧要的字符(t中不包含的字符)
  23. //或者left对应的字符那怕删掉 窗口中的字符也不会亏钱t中的字符
  24. //满足上面任意一点 那么 left++
  25. while (left < right && !isNecessary(left, s, owesCharCountMap)) {
  26. //当前left的字符
  27. char leftChar = s.charAt(left);
  28. left++;
  29. //当前窗口亏欠窗口中多少个
  30. Integer count = owesCharCountMap.get(leftChar);
  31. //如果不为null 说明leftChar 是t中的字符
  32. if (count != null) {
  33. //亏欠数++
  34. owesCharCountMap.put(leftChar, count + 1);
  35. }
  36. }
  37. //right位置的字符
  38. char rightChar = s.charAt(right);
  39. //right位置字符 窗口亏欠的数目
  40. Integer count = owesCharCountMap.get(rightChar);
  41. //right处字符是一个t中的字符 那么亏欠数-1
  42. if (count != null) {
  43. owesCharCountMap.put(rightChar, count - 1);
  44. }
  45. //如果窗口满足要求——指最起码不欠t中字符,及包含了所有t中的字符,那怕存在富足
  46. if (meetRequirementsOrNot(owesCharCountMap)) {
  47. //sub以下
  48. String tempRes = s.substring(left, right + 1);
  49. //记录
  50. if (res == null || tempRes.length() < res.length()) {
  51. res = tempRes;
  52. }
  53. //从窗口中 强制删除left位置处的字符
  54. //比如s=ADOBECODEBANC t = ABC 此时窗口中字符为ADOBEC 我们找到了一种结果,但是后续可能存在更好的答案
  55. //删除left位置的A 我们继续找更好的结果
  56. char leftChar = s.charAt(left);
  57. Integer leftCount = owesCharCountMap.get(leftChar);
  58. if (leftCount!=null){
  59. owesCharCountMap.put(leftChar,leftCount+1);
  60. }
  61. left++;
  62. }
  63. right++;
  64. }
  65. return res == null ? "" : res;
  66. }
  67. private boolean meetRequirementsOrNot(Map<Character, Integer> owesCharCountMap) {
  68. for (Integer v : owesCharCountMap.values()) {
  69. if (v == null) {
  70. continue;
  71. }
  72. if (v > 0) {
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. private boolean isNecessary(int left, String s, Map<Character, Integer> owesCharCountMap) {
  79. //left 位置的字符
  80. char leftChar = s.charAt(left);
  81. //当前亏欠map中的对应的亏欠数目
  82. Integer count = owesCharCountMap.get(leftChar);
  83. //为null 说明这个字符都不是t字符串中的字符 那么说明left位置的字符没必要存在于窗口中
  84. if (count == null) {
  85. return false;
  86. }
  87. //如果大于等于0 说明当前亏欠这个字符, 或者刚刚好,
  88. //如果移动那么窗口中的字符数将不够覆盖t中所有字符
  89. if (count >= 0) {
  90. return true;
  91. }
  92. //说明left处的字符不是必要的
  93. //说明 当前窗口中这个字符的数量已经大于t中这个字符的数量
  94. return false;
  95. }
  96. }

三丶[串联所有单词的子串](30. 串联所有单词的子串 - 力扣(Leetcode))

思路:

我的思路其实和第二题一样,也是恢复一个亏欠map 然后进行滑动窗口,只是这个开始滑动的位置应该是1~单个单词长度这个范围都进行滑动窗口,这一点很关键。

然后我们需要处理两种情况

  • 滑动窗口中包含了 words中不存在的单词 ,那么前功尽弃,我们需要从这个不存在单词的结尾继续滑动
  • 滑动窗口中包含单词1的数量大于了words数组中单词1的数量,那么其实我们应该从第一个出现单词1位置的下一个位置开始滑动

这个题推荐看题解30. 串联所有单词的子串 - 力扣(Leetcode)我的解法并不是很优秀

代码:

  1. class Solution {
  2. public List<Integer> findSubstring(String s, String[] words) {
  3. List<Integer> res = new ArrayList<>();
  4. int singleWordLen = words[0].length();
  5. if (singleWordLen * words.length > s.length()) {
  6. return res;
  7. }
  8. //亏欠map
  9. Map<String, Integer> owensMap = new HashMap<>();
  10. for (String loop : words) {
  11. owensMap.put(loop, owensMap.getOrDefault(loop, 0) + 1);
  12. }
  13. int roundStartPos = 0;
  14. //从第一个位置开始 ,第二个位置开始 。。到单个单词长度个位置
  15. while (roundStartPos < singleWordLen) {
  16. Map<String, Integer> owensMapTemp = new HashMap<>(owensMap);
  17. int left = roundStartPos;
  18. int right = roundStartPos;
  19. //滑动窗口
  20. while (right <= s.length() - singleWordLen) {
  21. //left 位置的单词 不是必要的
  22. while (left < right && !isNecessary(left, singleWordLen, s, owensMapTemp)) {
  23. String temp = s.substring(left, left + singleWordLen);
  24. Integer count = owensMapTemp.get(temp);
  25. if (count != null) {
  26. owensMapTemp.put(temp, count + 1);
  27. }
  28. left += singleWordLen;
  29. }
  30. //right位置的单词
  31. String rightString = s.substring(right, right + singleWordLen);
  32. Integer count = owensMapTemp.get(rightString);
  33. //right位置的单词 是我们需要的 那么维护亏欠map
  34. if (count != null && count >= 1) {
  35. owensMapTemp.put(rightString, count - 1);
  36. right += singleWordLen;
  37. } else {
  38. //right 位置的单词 不是words数组中的单词 那么直接然后right 跨过这个单词,直接从下一个单词开始
  39. if (count == null) {
  40. right = right + singleWordLen;
  41. left = right;
  42. owensMapTemp = new HashMap<>(owensMap);
  43. } else {
  44. //right位置的单词是words数组中的单词 但是当前窗口中这个单词数量 已经 大于words数组中这个单词数量的单词
  45. //那么删除头部的第一个单词 然后继续,
  46. String temp = s.substring(left, left + singleWordLen);
  47. Integer tempCount = owensMapTemp.get(temp);
  48. if (tempCount != null) {
  49. owensMapTemp.put(temp, tempCount + 1);
  50. }
  51. left += singleWordLen;
  52. }
  53. }
  54. //符合要求 那么left 移动到下一个单词 并继续 找出所有答案
  55. if (meetRequire(owensMapTemp)) {
  56. res.add(left);
  57. String temp = s.substring(left, left + singleWordLen);
  58. Integer tempCount = owensMapTemp.get(temp);
  59. if (tempCount != null) {
  60. owensMapTemp.put(temp, tempCount + 1);
  61. }
  62. left += singleWordLen;
  63. }
  64. }
  65. roundStartPos++;
  66. }
  67. return res;
  68. }
  69. private boolean isNecessary(int left, int singleWordLen, String s, Map<String, Integer> owensMapTemp) {
  70. String temp = s.substring(left, left + singleWordLen);
  71. Integer count = owensMapTemp.get(temp);
  72. if (count == null) {
  73. return false;
  74. }
  75. if (count < 0) {
  76. return false;
  77. }
  78. return true;
  79. }
  80. private boolean meetRequire(Map<String, Integer> owensMapTemp) {
  81. for (Integer c : owensMapTemp.values()) {
  82. if (c == null) {
  83. continue;
  84. }
  85. if (c > 0) {
  86. return false;
  87. }
  88. }
  89. return true;
  90. }
  91. }

四丶[重复的DNA序列](187. 重复的DNA序列 - 力扣(Leetcode))

思路:

这个题挺逆天的,很难想到怎么用滑动窗口做,使用2进制表示字母A,C,G,T,分别使用00,01,02,03,这样窗口滑动的时候就是第一个字母出去,意味着二进制表示左移位2,右边字符进来,使用位操作

代码:

  1. class Solution {
  2. public List<String> findRepeatedDnaSequences(String s) {
  3. if(s == null || s.length()<=10){
  4. return new ArrayList<>();
  5. }
  6. List<String> res = new LinkedList<>();
  7. Map<Integer,Integer> memory = new HashMap<Integer,Integer>();
  8. int right = 0;
  9. int firstBi = 0;
  10. while(right<10){
  11. firstBi = (firstBi<<2)| binaryOf(s.charAt(right));
  12. right++;
  13. }
  14. memory.put(firstBi,1);
  15. while(right < s.length()){
  16. int bi = binaryOf(s.charAt(right));
  17. //左边字符出去 右边字符进来
  18. firstBi = ((firstBi<<2) |bi)&((1<<20)-1);;
  19. int count =memory.getOrDefault(firstBi,0)+1;
  20. memory.put(firstBi,count);
  21. if(count == 2){
  22. res.add(s.substring(right+1-10,right+1));
  23. }
  24. right++;
  25. }
  26. return res;
  27. }
  28. private int binaryOf(char a){
  29. if(a == 'A'){
  30. return 0;
  31. }
  32. if(a == 'C'){
  33. return 1;
  34. }
  35. if(a == 'G'){
  36. return 2;
  37. }
  38. if(a == 'T'){
  39. return 3;
  40. }
  41. return -1;
  42. }
  43. }

五丶[长度最小的子数组](209. 长度最小的子数组 - 力扣(Leetcode))

思路:太简单了,窗口描述当前子数据,使用sum记录当前和,如果大于target那么更新长度,如果减去左边界的值还能大于,那么left++。直到right到 数组边界

  1. class Solution {
  2. public int minSubArrayLen(int target, int[] nums) {
  3. if(nums == null||nums.length == 0){
  4. return 0;
  5. }
  6. int left = 0;
  7. int right = 1;
  8. int sum =nums[0];
  9. int minLen = sum>target?1:0;;
  10. while(right<nums.length){
  11. sum +=nums[right];
  12. while(left<right && sum - nums[left]>=target){
  13. sum -= nums[left];
  14. left++;
  15. }
  16. if(sum>=target){
  17. if(minLen == 0||minLen>right-left+1){
  18. minLen = right - left+1;
  19. }
  20. }
  21. right++;
  22. }
  23. return minLen;
  24. }
  25. }

六丶[存在重复元素 II](219. 存在重复元素 II - 力扣(Leetcode))

思路:

维护一个长度为k的滑动窗口,使用set记录窗口中的数字,每次left位置的数据从窗口中出去,right位置的数进来,首先删除set中left代表的数字,然后如果right位置的数字存在于set中那么说明重复

代码:

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. if(nums == null || nums.length<=1){
  3. return false;
  4. }
  5. if(k == 0){
  6. return false;
  7. }
  8. int left = 0;
  9. int right = 0;
  10. Set<Integer>memory = new HashSet<Integer>();
  11. while(right<k+1 && right<nums.length){
  12. if(!memory.add(nums[right])){
  13. return true;
  14. }
  15. right++;
  16. }
  17. while(right <nums.length){
  18. int newNum = nums[right];
  19. memory.remove(nums[left++]);
  20. right++;
  21. if(!memory.add(newNum)){
  22. return true;
  23. }
  24. }
  25. return false;
  26. }

七丶[存在重复元素 III](220. 存在重复元素 III - 力扣(Leetcode))

思路:

思路和六类似,但是问题在于,我们如何快速的判断是否存在一个数,它和窗口中的数满足abs(nums[i] - nums[j]) <= t,这时候我们应该想到TreeSet,基于红黑树进行如此的判断的速度是logN

代码:

  1. class Solution {
  2. public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
  3. if (nums == null || nums.length == 0) {
  4. return false;
  5. }
  6. if (indexDiff == 0) {
  7. return false;
  8. }
  9. TreeSet<Integer> ts = new TreeSet<>();
  10. int left = 0;
  11. int right = 0;
  12. while (right < indexDiff + 1 && right < nums.length) {
  13. if (exist(ts,nums[right],valueDiff)){
  14. return true;
  15. }
  16. ts.add(nums[right]);
  17. right++;
  18. }
  19. while (right < nums.length) {
  20. ts.remove(nums[left++]);
  21. if (exist(ts,nums[right],valueDiff)){
  22. return true;
  23. }
  24. ts.add(nums[right++]);
  25. }
  26. return false;
  27. }
  28. private boolean exist(TreeSet<Integer> ts, int value, int diff) {
  29. //Set中是否 存在一个数A 满足 abs(A-value)<=diff
  30. //A>=value 最小的数 min 是否满足 min - value <= diff
  31. //A<=value 最大的数max 是否满足 value - max<= diff
  32. Integer min = ts.ceiling(value);
  33. if (min != null && min - value <= diff) {
  34. return true;
  35. }
  36. Integer max = ts.floor(value);
  37. if(max!=null&&value - max<=diff){
  38. return true;
  39. }
  40. return false;
  41. }
  42. }

八丶[滑动窗口最大值](239. 滑动窗口最大值 - 力扣(Leetcode))

思路:

窗口大小恒定为k大小,从头移动到尾巴,我们需要一种数据结构记录窗口此时的最大值,第一反应使用优先队列,入队时right位置的值,出队是left位置的值,但是这存在一个问题,如1,3,-1,3,2,2,k=3.当前窗口运动到1,【3,-1,3】,2,2 优先队列记录了3,-1紧接着left位置元素删除的时候会导致队列中只有一个1,随后right位置入队,队列维护了-1,2导致结构少了一个3。我们需要转变思想,队列每一个元素记录两个内容——值和对应的下标,当我们发生堆顶元素下标不在窗口中的时候进行删除。

上面优先队列的使用是整个复杂度来到NLogN,其实还有另外一个数据结构可以实现这个功能,单调栈——我们维护一个单调递减的栈,当j<i,并且i位置值大于j位置值的时候,我们还有什么必要维护j下标的值昵,

代码:

1.优先队列

  1. public int[] maxSlidingWindow(int[] nums, int k) {
  2. //优先队列 维护滑动窗口中的最大值
  3. if(nums == null || nums.length < k ){
  4. return nums;
  5. }
  6. int[]res = new int[nums.length - k +1];
  7. //优先使用值进行比较,值越大越在堆顶
  8. //其次使用下标进行比较,下表越大越在堆顶,下标越大 活得越久
  9. PriorityQueue<int[]> q = new PriorityQueue<>((i,j)->i[0]!=j[0]?j[0]-i[0]:j[1]-i[1]);
  10. int right = 0;
  11. while(right<k){
  12. q.add(new int[]{nums[right],right});
  13. right++;
  14. }
  15. res[0] = q.peek()[0];
  16. int count = 1;
  17. while(right<nums.length){
  18. q.offer(new int[]{nums[right],right});
  19. while(q.peek()[1] <= right - k){
  20. q.poll();
  21. }
  22. right++;
  23. res[count++]=q.peek()[0];
  24. }
  25. return res;
  26. }

2.单调栈

  1. public int[] maxSlidingWindow(int[] nums, int k) {
  2. if(nums == null ){
  3. return nums;
  4. }
  5. int[]res = new int[nums.length - k +1];
  6. //队列中的值是下标 但是必须保证这些下标值是单调递减的
  7. //当前 i<j nums[j]>=nums[i] 这时候num[i]对应下标 不需要维护了
  8. //说是单调栈其实是双向队列,因为我们需要看栈底元素
  9. LinkedList<Integer> ll = new LinkedList<Integer>();
  10. int right = 0;
  11. //初始化双端队列
  12. while(right < k){
  13. //nums[ll.getLast()] <= nums[right]
  14. //对应 1,2,3,4 k =3 初始化的时候 【1,2,3】4 这时候我们只需要维护3即可
  15. while(!ll.isEmpty() && nums[ll.getLast()] <= nums[right]){
  16. ll.removeLast();
  17. }
  18. ll.addLast(right);
  19. right++;
  20. }
  21. res[0] = nums[ll.getFirst()];
  22. int count = 1;
  23. while(right < nums.length){
  24. //同上
  25. while(!ll.isEmpty() && nums[ll.getLast()] <= nums[right]){
  26. ll.removeLast();
  27. }
  28. ll.addLast(right);
  29. //如果队列头 也就是最大的值 将不处于窗口外
  30. while(ll.getFirst() <= right-k){
  31. ll.removeFirst();
  32. }
  33. res[count++] = nums[ll.getFirst()];
  34. right++;
  35. }
  36. return res;
  37. }

九丶[找到字符串中所有字母异位词](438. 找到字符串中所有字母异位词 - 力扣(Leetcode))

思路:

滑动窗口大小为p长度,使用一个map记录窗口中字符和对应的数量,当每种字符数量和p相同是,记录下left的位置,left++的时候更新map,right++的时候更新map

代码:

  1. class Solution {
  2. public List<Integer> findAnagrams(String s, String p) {
  3. if(s == null || s.length()<p.length()){
  4. return new ArrayList<>();
  5. }
  6. List<Integer> res = new ArrayList<>();
  7. if(s.equals(p)){
  8. res.add(0);
  9. return res;
  10. }
  11. //记录p中的字符和对应的数量,因为都是小写字母,26长度的数组足以
  12. int[] pCharCount = new int[26];
  13. for(int i= 0; i<p.length();i++){
  14. char c = p.charAt(i);
  15. pCharCount[c-'a']++;
  16. }
  17. //记录窗口中字符和队友的数量
  18. int[] windowCharCount = new int[26];
  19. int left = 0 ;
  20. int right = 0;
  21. while(right<s.length()){
  22. //左边界++
  23. while(right - left + 1 > p.length()){
  24. windowCharCount[s.charAt(left)-'a']--;
  25. left++;
  26. }
  27. //右边界++
  28. windowCharCount[s.charAt(right)-'a']++;
  29. //字符和数目 和p一样
  30. if(meetRequire(pCharCount,windowCharCount)){
  31. res.add(left);
  32. }
  33. right++;
  34. }
  35. return res;
  36. }
  37. private boolean meetRequire(int[] pCharCount,int[] windowCharCount ){
  38. for(int i =0;i<26;i++){
  39. if(pCharCount[i]!=windowCharCount[i]){
  40. return false;
  41. }
  42. }
  43. return true;
  44. }
  45. }

十丶[替换后的最长重复字符](424. 替换后的最长重复字符 - 力扣(Leetcode))

思路:

维护一个窗口,我们需要保证窗口中的字符替换k次之后,都是相同的字符——字符总数-最大字符出现次数<=k

如果不满足这个条件 那么左边界++,直到满足

代码:

  1. class Solution {
  2. public int characterReplacement(String s, int k) {
  3. if(s == null ){
  4. return 0;
  5. }
  6. if(s.length() <=k){
  7. return s.length();
  8. }
  9. int res = 0;
  10. int left = 0;
  11. int right = 0;
  12. int[]charCount = new int[26];
  13. while(right<s.length()){
  14. charCount[s.charAt(right)-'A']++;
  15. while(!meetRequire(charCount,k)){
  16. charCount[s.charAt(left)-'A']--;
  17. left++;
  18. }
  19. res = Math.max(res,right - left+1);
  20. right++;
  21. }
  22. return res;
  23. }
  24. private boolean meetRequire(int[]charCount,int k){
  25. int max = -1;
  26. int sum = 0;
  27. for(int c : charCount){
  28. sum+=c;
  29. max = Math.max(max,c);
  30. }
  31. return sum-max<=k;
  32. }
  33. }

WeetCode2滑动窗口系列的更多相关文章

  1. leetcode的Hot100系列--3. 无重复字符的最长子串--滑动窗口

    可以先想下这两个问题: 1.怎样使用滑动窗口? 2.如何快速的解决字符查重问题? 滑动窗口 可以想象一下有两个指针,一个叫begin,一个叫now 这两个指针就指定了当前正在比较无重复的字符串,当再往 ...

  2. 面试连环炮系列(二十):TCP的滑动窗口协议是什么

    TCP的滑动窗口协议是什么 滑动窗口协议,用于网络数据传输时的流量控制,以避免拥塞的发生.该协议允许发送方在停止并等待确认前发送多个数据分组.由于发送方不必每发一个分组就停下来等待确认,因此该协议可以 ...

  3. [LeetCode]438. 找到字符串中所有字母异位词、76. 最小覆盖子串(滑动窗口解决子串问题系列)

    题目438. 找到字符串中所有字母异位词 给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引. 说明: 字母异位词指字母相同,但排列不同的字符 ...

  4. 源码分析 Alibaba sentinel 滑动窗口实现原理(文末附原理图)

    要实现限流.熔断等功能,首先要解决的问题是如何实时采集服务(资源)调用信息.例如将某一个接口设置的限流阔值 1W/tps,那首先如何判断当前的 TPS 是多少?Alibaba Sentinel 采用滑 ...

  5. [LeetCode] Sliding Window Maximum 滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  6. TCP/IP 协议中的滑动窗口

    一个例子明白发送缓冲区.接受缓冲区.滑动窗口协议之间的关系. 在上面的几篇文章中简单介绍了上述几个概念在TCP网络编程中的关系,也对应了几个基本socket系统调用的几个行为,这里再列举一个例子,由于 ...

  7. Storm Windowing storm滑动窗口简介

    Storm Windowing 简介 Storm可同时处理窗口内的所有tuple.窗口可以从时间或数量上来划分,由如下两个因素决定: 窗口的长度,可以是时间间隔或Tuple数量: 滑动间隔(slidi ...

  8. lintcode 滑动窗口的最大值(双端队列)

    题目链接:http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑动窗口的最大值 给出一个可能包含重复的整数数组,和一个大小为  ...

  9. TCP 三次握手四次挥手, ack 报文的大小.tcp和udp的不同之处、tcp如何保证可靠的、tcp滑动窗口解释

    一.TCP三次握手和四次挥手,ACK报文的大小 首先连接需要三次握手,释放连接需要四次挥手 然后看一下连接的具体请求: [注意]中断连接端可以是Client端,也可以是Server端. [注意] 在T ...

  10. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

随机推荐

  1. 【Elasticsearch】ES选主流程分析

    Raft协议 Raft是分布式系统中的一种共识算法,用于在集群中选举Leader管理集群.Raft协议中有以下角色: Leader(领导者):集群中的领导者,负责管理集群. Candidate(候选者 ...

  2. IK分词器实现原理剖析 —— 一个小问题引发的思考

    前言: 网上很多的文章都建议在使用IK分词器的时候,建立索引的时候使用ik_max_word模式:搜索的时候使用ik_smart模式.理由是max_word模式分词的结果会包含smart分词的结果,这 ...

  3. 《Java基础——选择语句》

    Java基础--选择语句       1. if语句; 规则: 1. 首先计算表达式的值. 2. 若表达式为真,则执行对应语句,为假则不执行.   格式一: if(表达式) 语句;//多个语句可用{} ...

  4. python的三层架构

    项目目录规范 Foo/ |-- core/ # 存放业务逻辑相关代码 | |-- core.py | |-- api/ # 存放接口文件,接口主要用于为业务逻辑提供数据操作. | |-- api.py ...

  5. Portainer 基本功能介紹之升級映像檔並更新 Container

    文档地址:https://www.asustor.com/zh-tw/online/College_topic?topic=145#dpt7

  6. Python实现改进后的Bi-RRT算法实例

    Python实现改进后的Bi-RRT算法实例 1.背景说明 以下代码是参照上海交通大学海洋工程国家重点实验室<基于改进双向RRT的无人艇局部路径规划算法研究>的算法思想实现的. 2.算法流 ...

  7. day08-MySQL事务

    MySQL事务 先来看一个例子 有一张balance表: 需求:将tom的100块钱转到King账户中 执行的操作是: update balance set money = money -100 wh ...

  8. ASP.NET Core :容器注入(二):生命周期作用域与对象释放

    //瞬时生命周期 ServiceCollection services = new ServiceCollection(); services.AddTransient<TestServiceI ...

  9. DDD-领域驱动(二)-贫血模型与充血模型

    贫血模型 一般来说 贫血模型:**一个类中只有属性或者成员变量,没有方法 **!例如 DbFirst 从数据库同步实体过来, -- 对于一个系统刚开始的时候会觉得这时候是最舒服的,但是如果后期系统需要 ...

  10. k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡

    k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡 前言 endpoint kube-proxy userspace 模式 iptables ipvs kernels ...