213. House Robber II
我好菜
1 | class Solution { |
分为rob第一个和不rob第一个,问题变为rob[1, n - 2]和rob[2, n - 1]
我好菜
1 | class Solution { |
分为rob第一个和不rob第一个,问题变为rob[1, n - 2]和rob[2, n - 1]
我好菜
1 | class Solution { |
1 | class Solution { |
因为第一行和第一列为0都由一个matrix[0][0]指定,将导致二者无法区分,所以用matrix[0][0]指定第一行,isCol这个额外的变量指定第一列。
注意要先填充第一行第一列以外的内容再去填充第一行第一列,不然后面数据会被填充的0所干扰
1 | class Solution { |
1 | class Solution { |
My vegetable exploded
1 | class Solution { |
三步走,先处理交叠前的,在处理正在交叠的,再添加剩下的
review
1 | class Solution { |
1 | class Solution { |
当height[i] < height[j]
时,如果不舍弃他而移动右边j,那么结果肯定时小于现在的,所以舍弃i
假设a2,a6为最大,需要证明当left=a2时,右边会移到a6。 即当left=a2,right=a7的下一位时left=a2,left=a6。而这一步必然时height[a2]>height[a7],若不然,则最小边界为a2,宽度只会减少,则总值减少,所以必定移动a.
题目: 1
2
3
4
5Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*' where:
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
思路:
.
可以匹配任何字符,因此当遇到了.
那就是直接匹配成功,其余状况就是比较字符是否相等即可。*
可以匹配之前的元素,0次或多次,当匹配0次的时候,那么就将原text和pattern除去这一匹配0次的模式后的部分再次进行匹配,当匹配一次或多次的时候,就在text中删去匹配成功的部分继续把剩下的和pattern匹配,由于每一都会有这2种抉择,所以采用递归,二者状况其一匹配成功即可。
当pattern为空时,当且仅到s为空才会匹配成功
1 | class Solution { |
1 | enum status { |
由于递归检索过程中会出现许多的交叠,因此自然而然想到避免这种重复,所以通过dp保存起来以供后续读取,其中vector的size全都+1是防止溢出。
而且将substr的工作转为有i,j表示,避免了多次创建string
但是这种仅仅可以避免交叠,top-down,顾名思义,从大往下走,分为一个个小问题从而解决,转而使用bottom-up,一个个小问题进行组合合成大问题
1 | class Solution { |
base为当两者全为空的时候,匹配结果为true。
从后面往前走,当i == 0 && j == 0
时,表示匹配了整个字符串和pattern
如果从前往后,不便于计算下标
然后分解成小问题,对于当前dp[i][j]来说,从递归的思想引过来
p[j] == '.'
或p[j] == s[i]
,那么dp[i][j] == dp[i + 1][j + 1]
,说明当前匹配可以正常走,结果=除了这个位之后的匹配结果p[j + 1] == '*'
,那么`dp[i][j] == dp[i][j + 2] || s[i] == p[j] || p[j] == '.' &&dp[i + 1][j],这是可以匹配s[i]的0个或多个,当0个时候,这匹配没有生效,所以取后两位继续匹配的结果,当匹配多个,那么p[j]被使用了,结果就是当p[j]匹配成功后,结合后面串的匹配结果得出当前的结果。1 | class Solution { |
stack中存储坐标,括号两端(左端为括号开始的前一个, 右端为当前括号)构成最长的值。先push(-1)是便于计算,每遇到一个)就pop出一个,空的时候就push,为了方便后面计算坐标。
1 | class Solution { |
1 | class Solution { |
对于s[i] == ')'
这时一个括号要收尾
s[i - 1] == '('
,则dp[i] = dp[i - 2] + 2
s[i - 1] == ')'
,此时如果s[i-1]
有配对的'('
或者多个合法的配对,那么通过先前这个的长度往前减坐标寻找是否有与s[i]
配对的'('
若有,则这个与其配对的将之中包裹的合法括号和先前的合法括号连接相加dp[i] = dp[i - dp[i - 1] - 2] + dp[i - 1] + 2
1 | class Solution { |
1 | class Solution { |
r
1 | class Solution { |
1 | class Solution { |
遇见(
就增加left,遇见)
就增加right,当二者相等时候,表明所有(
和)
配对了,计算长度,更新max
从左到右时,当right>left,表示前面遇到的(
比)
少,因此由于括号的顺序,不可能再长下去了,由此重置left和right继续开始计数
从右往左时,当left>right, 表示前面遇到的)
比(
少,同理
要从左往右和从右往左都走一遍是因为... 证明:[@wander](https://leetcode.com/wanders/) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22Proof of validity for approach 4:
Let i and j denote the starting and ending indices of the longest valid subsequence.
Note that in the forward pass after (fully) processing each character, it's always the case that left >= right. (*)
This is in particular true after processing i-1 (immediately before processing i).
Case 1: If immediately before i left = right, then the forward pass will detect the length of the longest valid subsequence.
(The number of '(' and ')' is the same for any valid subseq. Thus after processing j, left = right.)
Case 2: If immediately before i left > right, the forward pass will not detect the longest valid subsequence, but we claim the backward pass will.
Similar to observation (*) above, note that right >= left after fully processing each element in the backward pass. We detect the longest valid subsequence in the backward pass if and only if right = left after processing j+1 (immediately before processing j).
So what if right > left (in the backward pass immediately before processing j)?
Well, then the maximality of our subsequence from i to j would be contradicted.
Namely, we can increase j to j' so that (j,j'] has one more ')' than '(', and decrease i to i', so that [i',i) has one more '(' than ')'.
The resulting subsequence from i' to j' will have longer length and will still be valid (the number of '(' and ')' will be incremented by the same amount).
Thus, either the backward pass or forward pass (possibly both) will detect the longest valid subsequence.
Edit: as @papercup points out in response to @bmunot9 , one can take i' = i - 1 and j' = j + 1, since
left > right immediately before i in the forward pass implies that s[i] == '(', otherwise maximality would already be contradicted (one could find i0<i such that s[i0,i) is valid, and thus s[i0,j] would be valid). Similarly
right > left immediately after j+1 (before j) in the backward pass implies s[j] == ')'
1 | class Solution { |
一个长度为n的数列中,如果所有正数都没缺失,那么必然是1,2,3,4...排列,且一个数a的正确位置必定是在a-1处,因此如果A[i]
不处在A[A[i] - 1]
,那么交换A[i]
和A[A[i] - 1]
让他去正确位置,由此直到所有该到正确位置的到正确位置,其中<=0和>n的数没有正确位置,所以终止。 排好位置后再遍历
1 | class Solution { |
引用一段解释[@triton11](https://leetcode.com/triton11/) 1
So consider an array like [1,4,3,3,3]. The length is 5, so n = 5. For each item, we are basically overwriting the spot at the index of the item with 5 + spot. So, at index 0 we have a 1, and 1%5 is 1, so we replace the item at index 1 with 5 + that item. Now our array is [1,9,3,3,3]. Next, at index 1 we have a 9, and 9%5 is 4 (notice how adding 5 didn't change the fact that we can still find the original value with % 5), so we replace the item at index 4 with 5 + that item. Our array is now [1, 9, 3, 3, 8]. Continuing, we get [1, 9, 3, 8, 8] then [1, 9, 3, 13, 8] and finally [1, 9, 3, 18, 8]. When we iterate through to find the values at the end, starting at index 1, we find that 9/5 is greater than 1, 3/5 is not greater than 1, 13/5 and 8/5 are greater than 1. Thus, since 3/5 is the first not greater than 5, we know index 2 was never used or added to, so 2 is the missing number. Feel free to comment if you have Qs or if I made any mistakes.
1 | /** |
稍微改改,思想没变,但可以少1次的判断 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Solution {
public:
int maxPathSum(TreeNode* root) {
int curMax = INT_MIN;
helper(root, curMax);
return curMax;
}
private:
int helper(TreeNode* node, int& curMax)
{
if(!node)
return 0;
auto left = max(helper(node->left, curMax), 0);
auto right = max(helper(node->right, curMax), 0);
auto curSum = left + right + node->val;
curMax = max(curSum, curMax);
return max(left, right) + node->val;
}
};
1 | class Solution { |
只记录存在于t中的字符的坐标
1 | class Solution { |
review 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
33class Solution {
public:
string minWindow(string s, string t) {
int n = s.size();
unordered_map<char, int> map;
for(auto ch : t)
++map[ch];
int count = map.size();
int begin = 0, end = 0;
int rl = 0;
int subSize = INT_MAX;
while(end < n)
{
if(--map[s[end]] == 0)
--count;
while(count == 0)
{
if(end - begin + 1 < subSize)
{
rl = begin;
subSize = end - begin + 1;
}
if(++map[s[begin]] > 0)
++count;
++begin;
}
++end;
}
if(subSize == INT_MAX)
return "";
return s.substr(rl, subSize);
}
};