0%

leetcode 76 Solution

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.demo.s76;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* 最小覆盖子串
* 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
*
*  
*
* 注意:
*
* 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
* 如果 s 中存在这样的子串,我们保证它是唯一的答案。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/minimum-window-substring
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
//t 中每个字符出现的次数 存到 ori中
Map<Character, Integer> ori = new HashMap<Character, Integer>();
//记录字符串 s 子串中字符出现次数
Map<Character, Integer> cnt = new HashMap<Character, Integer>();

public String minWindow(String s, String t) {
int tLen = t.length();
//遍历t 统计出 ori
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;
//子字符串长度len
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int sLen = s.length();
//子字符串从 0 开始 到 r
while (r < sLen) {
++r;
//如果 s字符串的字符出现了 t总字符
if (r < sLen && ori.containsKey(s.charAt(r))) {
//则累加值 放到cnt中计数
cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
}
//如果满足要求了,尝试缩短子串
while (check() && l <= r) {
//如果比当前最小长度len 还小 则 更新len
if (r - l + 1 < len) {
len = r - l + 1;
ansL = l;
ansR = l + len;
}
// l 左移 对应统计cnt中字符数字也要减1
if (ori.containsKey(s.charAt(l))) {
cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
}
++l;
}
}
//如果ansL 存在 则返回 子字符串
return ansL == -1 ? "" : s.substring(ansL, ansR);
}

public boolean check() {
//检查是否完全满足 t的字符及出现次数要求
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;
}
}