Skip to content

Commit

Permalink
修改
Browse files Browse the repository at this point in the history
  • Loading branch information
arkingc committed Aug 29, 2018
1 parent 32a2095 commit c51dda4
Showing 1 changed file with 23 additions and 33 deletions.
56 changes: 23 additions & 33 deletions 数据结构与算法/算法题总结.md
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,7 @@ public:

### 解答

假设两个字符串序列为X和Y,从结尾字符进行分析(设`n`和`m`为两个字符串的长度):
假设两个字符串序列为`X`和`Y`,从结尾字符进行分析(设`n`和`m`为两个字符串的长度):

* 如果结尾字符相等,那么问题转换为求序列`X(n-1)`和`Y(m-1)`的最长公共子序列,即:`LCS(X(n-1),Y(m-1)) + 1`
* 如果结尾字符不相等,那么问题转换成求`max(LCS(X(n-1),Y(m)),LCS(X(n),Y(m-1)))`
Expand Down Expand Up @@ -2374,6 +2374,9 @@ public:
};
```

<br>
<br>

## 判断字符串是否表示一个数值

OJ链接:[牛客网](https://www.nowcoder.com/practice/6f8c901d091949a5837e24bb82a731f2?tpId=13&tqId=11206&tPage=3&rp=3&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking)、[Leetcode](https://leetcode.com/problems/valid-number/description/)
Expand All @@ -2400,11 +2403,11 @@ OJ链接:[牛客网](https://www.nowcoder.com/practice/6f8c901d091949a5837e24b

**2)`'e'`或`'E'`能且仅能出现1次,并且只有`num1`为真后才能出现**

**3)`'.'`只能出现在part1中,并且只能出现1次**
**3)`'.'`只能出现在`part1`中,并且只能出现1次**

**4)`'+'`和`'-'`只能出现在`part1`或`part2`的开始**

**5)`'空格'`只能出现在`part1`之前,part2之后,所以使用指针`start`指向`part1`的第一个字符,指针`end`指向`part2`的最后一个字符,然后只处理`start`到`end`的字符**
**5)`'空格'`只能出现在`part1`之前、`part2`之后,所以使用指针`start`指向`part1`的第一个字符,指针`end`指向`part2`的最后一个字符,然后只处理`start`到`end`的字符**

```c++
class Solution {
Expand Down Expand Up @@ -2569,25 +2572,16 @@ public:
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int positions[256];
vector<int> count(256,0);

for(int i = 0;i < 256;i++){
positions[i] = -1;
}
for(const char &c : str)
count[c]++;

int sz = str.size();
for(int i = 0;i < sz;i++){
if(positions[str[i]] == -1)
positions[str[i]] = i;
else
positions[str[i]] = -2;
}
for(int i = 0;i < str.length();i++)
if(count[str[i]] == 1)
return i;

int minidx = sz - 1;
for(int j = 0;j < 256;j++)
if(positions[j] >= 0 && positions[j] < minidx)
minidx = positions[j];
return minidx;
return -1;
}
};
```
Expand Down Expand Up @@ -2801,7 +2795,8 @@ public:

### 解答

在求n个字符的长度为m的组合时,把这n个字符分成两部分:第一个字符和其余所有字符。如果组合里包含第一个字符,则下一步在剩余字符里面选取m-1个字符;如果组合里不包含第一个字符,则下一步在剩余的n-1个字符里选取m个字符
* 如果字符串不含重复字符,参考[不含重复元素集合的所有子集](#不含重复元素集合的所有子集)
* 如果字符串包含相同字符,参考[含重复元素集合的所有子集](#含重复元素集合的所有子集)

<br>
<br>
Expand Down Expand Up @@ -10401,8 +10396,8 @@ wordDict = ["cats", "dog", "sand", "and", "cat"]
对于字符串`s`,设其所有可能的句子为`f(s)`,字典为`dict`

* 如果`left = s`包含在`dict`中,设`right = s.substr(len)`,如果`f(right)`能够由`dict`构建为句子,那么`f(s) += append(s,f(right))`(`append`表示在`f(right)`的所有结果前加上`s + ' '`)
* 如果`left = s.substr(0,len - 1)`包含在`dict`中,设`right = s.substr(len - 1)`,如果`f(right)`能够由`dict`构建为句子,那么`f(s) += append(right)`
* 如果`left = s.substr(0,len - 2)`包含在`dict`中,设`right = s.substr(len - 2)`,如果`f(right)`能够由`dict`构建为句子,那么`f(s) += append(right)`
* 如果`left = s.substr(0,len - 1)`包含在`dict`中,设`right = s.substr(len - 1)`,如果`f(right)`能够由`dict`构建为句子,那么`f(s) += append(s,f(right))`
* 如果`left = s.substr(0,len - 2)`包含在`dict`中,设`right = s.substr(len - 2)`,如果`f(right)`能够由`dict`构建为句子,那么`f(s) += append(s,f(right))`
* ...

从上面可以看出,每个问题`f`可以转化成一个规模更小的子问题。但是在求子问题时可能会重复计算,因此,如果以前求过`f(right)`,那么当需要再次求`f(right)`时,为了避免重复计算,希望快速得到结果,因此使用`mem`记录每个已经求得的子问题的值,那么有2种方案:
Expand All @@ -10418,11 +10413,11 @@ wordDict = ["cats", "dog", "sand", "and", "cat"]
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
```

* 如果使用**迭代**,那么从`s`最右边开始,会分别求出`"s"`、`"ss"`、`"sss"`、`"ssss"`,,...的解,然后保存
* 如果使用**迭代**,那么从`s`最右边开始,会分别求出`"a"`、`"aa"`、`"aaa"`、`"aaaa"`,,...的解,然后保存
* 如果使用**递归**
- 因为`left = s.substr(0,len - 1)`中包含了`b`,因此不在`dict`,所以不会进一步求`"s"`的解
- 因为`left = s.substr(0,len - 2)`中包含了`b`,因此不在`dict`,所以不会进一步求`"ss"`的解
- 因为`left = s.substr(0,len - 3)`中包含了`b`,因此不在`dict`,所以不会进一步求`"sss"`的解
- 因为`left = s.substr(0,len - 1)`不在`dict`,所以不会进一步求`"s"`的解
- 因为`left = s.substr(0,len - 2)`不在`dict`,所以不会进一步求`"ss"`的解
- 因为`left = s.substr(0,len - 3)`不在`dict`,所以不会进一步求`"sss"`的解
- ...
- 因为`left = s.substr(0,10)`在`dict`中,所以进一步求`right = s.substr(10)`的解
+ 最终会递归到求`right = "baaaa...."`的解,由于任意`right.substr(0,k)`都不再`dict`中,所以返回一个空结果,即`baaa....`不能由`dict`构成句子,那么最终结果也就是`s`也不能由`dict`构成句子
Expand Down Expand Up @@ -12842,10 +12837,10 @@ public:
//如果++没有大于0,说明是遇到一个在滑动窗口中出现多次的字符
//因此不增加total
if(map.find(s[i]) != map.end()){
if(++map[s[i++]] > 0)
if(++map[s[i]] > 0)
total++;
}
else i++;
i++;
}
}

Expand Down Expand Up @@ -15887,11 +15882,6 @@ public:

words中的单词长度相同,设为len。因此要判断是否满足要求,即判断相连的count个长度为len的子串是否都在map中。由于子串出现的次数必须和map中单词的次数相等,因此查找时每找到一个单词,map中单词的计数减1

复杂度(设n为字符串长度,m为单词个数)

* 时间复杂度:O(n \* m)
* 空间复杂度:O(m)

```c++
class Solution {
public:
Expand Down

0 comments on commit c51dda4

Please sign in to comment.