1.Simplify Path 简化路径
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
Corner Cases:
- Did you consider the case where path =
"/../"
?
In this case, you should return"/"
. - Another corner case is the path might contain multiple slashes
'/'
together, such as"/home//foo/"
.
In this case, you should ignore redundant slashes and return"/home/foo"
.
C++中也有专门处理字符串的机制,我们可以使用stringstream来分隔字符串,然后对每一段分别处理,思路和上面的方法相似,参见代码如下:
class Solution {
public:
string simplifyPath(string path) {
string res, t;
stringstream ss(path);
vector<string> v;
while (getline(ss, t, '/')) {
if (t == "" || t == ".") continue;
if (t == ".." && !v.empty()) v.pop_back();
else if (t != "..") v.push_back(t);
}
for (string s : v) res += "/" + s;
return res.empty() ? "/" : res;
}
};
2.最小窗口子串
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
Note:
- If there is no such window in S that covers all characters in T, return the empty string
""
. - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
这道题给了我们一个原字符串S,还有一个目标字符串T,让我们在S中找到一个最短的子串,使得其包含了T中的所有的字母,
我们还是从简单的例子来分析吧,题目例子中的S有点长,我们换个短的 S = "ADBANC",T = "ABC",那么我们肉眼遍历一遍S呗,首先第一个是A,嗯很好,T中有,第二个是D,T中没有,不理它,第三个是B,嗯很好,T中有,第四个又是A,多了一个,礼多人不怪嘛,收下啦,第五个是N,一边凉快去,第六个终于是C了,那么貌似好像需要整个S串,其实不然,我们注意之前有多一个A,但么我们就算去掉第一个A,也没事,因为第四个A可以代替之,第二个D也可以去掉,因为不在T串中,第三个B就不能再去掉了,不然就没有B了。所以最终的答案就"BANC"了。通过上面的描述,你有没有发现一个有趣的现象,我们是先扩展,再收缩,就好像一个窗口一样,先扩大右边界,然后再收缩左边界,上面的例子中我们是右边界无法扩大了后才开始收缩左边界,实际上对于复杂的例子,有可能是扩大右边界,然后缩小一下左边界,然后再扩大右边界等等。这就很像一个不停滑动的窗口了,这就是大名鼎鼎的滑动窗口Sliding Window了,简直是神器啊,能解很多子串,子数组,子序列等等的问题,是必须要熟练掌握的啊!
- 我们最开始先扫描一遍T,把对应的字符及其出现的次数存到HashMap中。
- 然后开始遍历S,就把遍历到的字母对应的HashMap中的value减一,如果减1后仍大于等于0,cnt自增1。
- 如果cnt等于T串长度时,开始循环,纪录一个字串并更新最小字串值。然后将子窗口的左边界向右移,如果某个移除掉的字母是T串中不可缺少的字母,那么cnt自减1,表示此时T串并没有完全匹配。
class Solution {
public:
string minWindow(string s, string t) {
string res = "";
unordered_map<char, int> letterCnt;
int left = 0, cnt = 0, minLen = INT_MAX;
for (char c : t) ++letterCnt[c];
for (int i = 0; i < s.size(); ++i) {
if (--letterCnt[s[i]] >= 0) ++cnt;
while (cnt == t.size()) {
if (minLen > i - left + 1) {
minLen = i - left + 1;
res = s.substr(left, minLen);
}
if (++letterCnt[s[left]] > 0) --cnt;
++left;
}
}
return res;
}
};