76. 最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
每次让R++一次,然后尽可能的移动L ```java class Solution { Map
ori = new HashMap (); Map cnt = new HashMap (); public String minWindow(String s, String t) {
int tLen = t.length();
for (int i = 0; i < tLen; i++) {
char c = t.charAt(i);
ori.put(c, ori.getOrDefault(c, 0) + 1);
}
int l = 0, r = -1;
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int sLen = s.length();
while (r < sLen) {
++r;
if (r < sLen && ori.containsKey(s.charAt(r))) {
cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
}
while (check() && l <= r) {
if (r - l + 1 < len) {
len = r - l + 1;
ansL = l;
ansR = l + len;
}
if (ori.containsKey(s.charAt(l))) {
cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
}
++l;
}
}
return ansL == -1 ? "" : s.substring(ansL, ansR);
}
public boolean check() {
Iterator iter = ori.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (cnt.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
} }
<a name="lwLVd"></a>
#### [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/)
![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 />动态规划可以做,也可以使用双指针
- 对于任意‘(’、‘ )’ 与他们匹配的都是唯一的一个
- **括号序列合法 <=> 所有的前缀和>=0,并且总和=0**
**做法:**
- start表示当前一段的开头,cnt表示前缀和
- (=1,)=-1
- cnt<0 =》 start = i+1,cnt=0
- 为什么不是start++?因为对于当前的i(当前i指向的一定是‘)’)来说,在他之前没有一个左括号与他进行匹配,所以包含它的永远不是合法的。
- cnt>0 => 继续做
- cnt==0 ==》 [start,i]合法,可以更新最大值
- 最后需要倒过来对称的做一次
```java
class Solution {
public int longestValidParentheses(String s) {
int a = count(s);
// 对于(((( ))) 得到的是0,这时候需要反过来对称再做一次:
// 先倒过来,在左右括号相互转化
//((( ))))
char[] ch = s.toCharArray();
for (int i = 0, j = ch.length - 1; i < j; i++, j--) {
char c = ch[i];
ch[i] = ch[j];
ch[j] = c;
}
for (int i = 0; i < ch.length; i++) {
ch[i] = ch[i] == '(' ? ')' : '(';
}
return Math.max(a, count(new String(ch)));
}
int count(String s) {
int res = 0;
int start = 0;
int cnt = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') cnt++;
else {
cnt--;
if (cnt < 0) { // 当前所指向的右括号全局无法匹配,需要重新开始新的序列
start = i + 1;
cnt = 0;
} else if (cnt == 0)
res = Math.max(res, i - start + 1);
}
}
return res;
}
}