76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
image.pngimage.png
image.png

  • 每次让R++一次,然后尽可能的移动L ```java class Solution { Map ori = new HashMap(); Map cnt = new HashMap();

    public String minWindow(String s, String t) {

    1. int tLen = t.length();
    2. for (int i = 0; i < tLen; i++) {
    3. char c = t.charAt(i);
    4. ori.put(c, ori.getOrDefault(c, 0) + 1);
    5. }
    6. int l = 0, r = -1;
    7. int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
    8. int sLen = s.length();
    9. while (r < sLen) {
    10. ++r;
    11. if (r < sLen && ori.containsKey(s.charAt(r))) {
    12. cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
    13. }
    14. while (check() && l <= r) {
    15. if (r - l + 1 < len) {
    16. len = r - l + 1;
    17. ansL = l;
    18. ansR = l + len;
    19. }
    20. if (ori.containsKey(s.charAt(l))) {
    21. cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
    22. }
    23. ++l;
    24. }
    25. }
    26. return ansL == -1 ? "" : s.substring(ansL, ansR);

    }

    public boolean check() {

    1. Iterator iter = ori.entrySet().iterator();
    2. while (iter.hasNext()) {
    3. Map.Entry entry = (Map.Entry) iter.next();
    4. Character key = (Character) entry.getKey();
    5. Integer val = (Integer) entry.getValue();
    6. if (cnt.getOrDefault(key, 0) < val) {
    7. return false;
    8. }
    9. }
    10. return true;

    } }

  1. <a name="lwLVd"></a>
  2. #### [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/)
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/8429887/1612246959809-e6a632f5-8f42-46d2-bd25-88efcfea5219.png#align=left&display=inline&height=718&margin=%5Bobject%20Object%5D&name=image.png&originHeight=718&originWidth=720&size=52514&status=done&style=none&width=720)<br />动态规划可以做,也可以使用双指针
  4. - 对于任意‘(’、‘ )’ 与他们匹配的都是唯一的一个
  5. - **括号序列合法 <=> 所有的前缀和>=0,并且总和=0**
  6. **做法:**
  7. - start表示当前一段的开头,cnt表示前缀和
  8. - (=1,)=-1
  9. - cnt<0 =》 start = i+1,cnt=0
  10. - 为什么不是start++?因为对于当前的i(当前i指向的一定是‘)’)来说,在他之前没有一个左括号与他进行匹配,所以包含它的永远不是合法的。
  11. - cnt>0 => 继续做
  12. - cnt==0 ==》 [start,i]合法,可以更新最大值
  13. - 最后需要倒过来对称的做一次
  14. ```java
  15. class Solution {
  16. public int longestValidParentheses(String s) {
  17. int a = count(s);
  18. // 对于(((( ))) 得到的是0,这时候需要反过来对称再做一次:
  19. // 先倒过来,在左右括号相互转化
  20. //((( ))))
  21. char[] ch = s.toCharArray();
  22. for (int i = 0, j = ch.length - 1; i < j; i++, j--) {
  23. char c = ch[i];
  24. ch[i] = ch[j];
  25. ch[j] = c;
  26. }
  27. for (int i = 0; i < ch.length; i++) {
  28. ch[i] = ch[i] == '(' ? ')' : '(';
  29. }
  30. return Math.max(a, count(new String(ch)));
  31. }
  32. int count(String s) {
  33. int res = 0;
  34. int start = 0;
  35. int cnt = 0;
  36. for (int i = 0; i < s.length(); i++) {
  37. if (s.charAt(i) == '(') cnt++;
  38. else {
  39. cnt--;
  40. if (cnt < 0) { // 当前所指向的右括号全局无法匹配,需要重新开始新的序列
  41. start = i + 1;
  42. cnt = 0;
  43. } else if (cnt == 0)
  44. res = Math.max(res, i - start + 1);
  45. }
  46. }
  47. return res;
  48. }
  49. }