日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2020.12.17

發布時間:2025/4/16 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020.12.17 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2020.12.17

1.無重復字符的最長子串(leetcode3)

思路:使用滑動窗口機制

設置右指針移動,其實就是一個隊列,比如例題中的 abcabcbb,進入這個隊列(窗口)為 abc 滿足題目要求,當再進入 a,隊列變成了 abca,這時候不滿足要求。所以,我們要移動這個隊列!

如何移動?我們只要把隊列的左邊的元素移出就行了,直到滿足題目要求!

一直維持這樣的隊列,找出隊列出現最長的長度時候,求出解!

public int lengthOfLongestSubstring(String s) {//HashMap<Character, Integer> map = new HashMap<>();int[] map = new int[128];//使用int數組可以當做map使用int maxLen = 0;//用于記錄最大不重復子串的長度int left = 0;//滑動窗口左指針for (int i = 0; i < s.length() ; i++){/**1、首先,判斷當前字符是否包含在map中,如果不包含,將該字符添加到map(字符,字符在數組下標),此時沒有出現重復的字符,左指針不需要變化。此時不重復子串的長度為:i-left+1,與原來的maxLen比較,取最大值;2、如果當前字符 ch 包含在 map中,此時有2類情況:1)當前字符包含在當前有效的子段中,如:abca,當我們遍歷到第二個a,當前有效最長子段是 abc,我們又遍歷到a,那么此時更新 left 為 map.get(a)+1=1,當前有效子段更新為 bca;2)當前字符不包含在當前最長有效子段中,如:abba,我們先添加a,b進map,此時left=0,我們再添加b,發現map中包含b,而且b包含在最長有效子段中,就是1)的情況,我們更新 left=map.get(b)+1=2,此時子段更新為 b,而且map中仍然包含a,map.get(a)=0;隨后,我們遍歷到a,發現a包含在map中,且map.get(a)=0,如果我們像1)一樣處理,就會發現 left=map.get(a)+1=1,實際上,left此時應該不變,left始終為2,子段變成 ba才對。為了處理以上2類情況,我們每次更新left,left=Math.max(left , map.get(ch)+1).另外,更新left后,不管原來的 s.charAt(i) 是否在最長子段中,我們都要將 s.charAt(i) 的位置更新為當前的i,因此此時新的 s.charAt(i) 已經進入到 當前最長的子段中!*///if(map.containsKey(s.charAt(i)))if (map[s.charAt(i)] != -1){left = Math.max(left, map[s.charAt(i)]+1);//left = Math.max(left , map.get(s.charAt(i))+1);}//不管是否更新left,都要更新 s.charAt(i) 的位置!map.put(s.charAt(i) , i);maxLen = Math.max(maxLen , i-left+1);}return maxLen; }

2.最小覆蓋子串(leetcode76)

思路:使用滑動窗口機制

  • 設置右指針right移動,使滑動窗口增大,直到窗口包含了T的所有元素。
  • 不斷增加左指針left使滑動窗口縮小,并查看窗口是否包含所有元素。如果滿足則記錄此時滑動窗口的長度,并保存最小值
  • 讓left再增加一個位置,這個時候滑動窗口肯定不滿足條件了,那么繼續從步驟一開始執行,尋找新的滿足條件的滑動窗口,如此反復,直到right超出了字符串S范圍。
  • 其中,需要注意的是:判斷是否包含所有元素的方法是利用兩個hashmap集合實現(也可以直接用數組表示),key為字符,value為字符的次數。滿足條件對應的是window集合中元素個數要大于等于need集合中元素個數,在這里利用valid來判斷是否滿足條件。

    class Solution {public String minWindow(String s, String t) {if (s == null || s.length() < t.length())return "";HashMap<Character, Integer> need = new HashMap<>();HashMap<Character, Integer> window = new HashMap<>();for (Character ch : t.toCharArray()) {need.put(ch, need.getOrDefault(ch,0)+1);}int left = 0;int valid = 0;int len = Integer.MAX_VALUE;int start = 0;for (int right=0;right<s.length();right++) {Character c1 = s.charAt(right);if (need.containsKey(c1)) {window.put(c1, window.getOrDefault(c1,0)+1);if (need.get(c1).equals(window.get(c1))) {valid++;}}while (valid == need.size() && left<=right) {if (right-left<len) {start = left;len = right-left+1;}Character c2 = s.charAt(left);if (need.containsKey(c2)) {window.put(c2, window.getOrDefault(c2,0)-1);if (window.get(c2) < need.get(c2)) {valid--;}}left++;}}return len==Integer.MAX_VALUE ? "" : s.substring(start, start+len);} }

    3.滑動窗口最大值(leetcode239)

    思路:使用單調遞減棧實現,即雙端隊列。

  • 遍歷數組,將數組對應的下標存入隊列中。
  • 數組需要按照數(即下標對應數組中的值)從大到小排列,如果當前遍歷的數比隊尾的值大,則需要彈出隊尾值,直到隊列重新滿足從大到小的要求。
  • 每次取隊列頭部即窗口最大值。如果頭部位置已經超出窗口左邊界的話,則移除頭部。
  • class Solution {public int[] maxSlidingWindow(int[] nums, int k) {if(nums == null || nums.length < 2) return nums;// 雙向隊列 保存當前窗口最大值的數組位置 保證隊列中數組位置的數值按從大到小排序LinkedList<Integer> queue = new LinkedList();// 結果數組int[] result = new int[nums.length-k+1];// 遍歷nums數組for(int i = 0;i < nums.length;i++){// 保證從大到小 如果前面數小則需要依次彈出,直至滿足要求while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){queue.pollLast();}// 添加當前值對應的數組下標queue.addLast(i);// 判斷當前隊列中隊首的值是否有效if(queue.peek() <= i-k){queue.poll(); } // 當窗口長度為k時 保存當前窗口中最大值if(i+1 >= k){result[i+1-k] = nums[queue.peek()];}}return result;} }

    總結

    以上是生活随笔為你收集整理的2020.12.17的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。