Skip to content

Commit c0c1eb3

Browse files
committed
update clean code
1 parent af75a19 commit c0c1eb3

File tree

2 files changed

+17
-60
lines changed

2 files changed

+17
-60
lines changed

string/compare_strings.md

Lines changed: 13 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ For A = "ABCD" B = "AABC", return false.
1717

1818
## 题解
1919

20-
题目意思是问B中的所有字符是否都在A中,而不是单个字符。比如B="AABC"包含两个「A」,而A="ABCD"只包含一个「A」,故返回false.
20+
[Two Strings Are Anagrams | Data Structure and Algorithm](http://algorithm.yuanbin.me/string/two_strings_are_anagrams.html) 的变形题。题目意思是问B中的所有字符是否都在A中,而不是单个字符。比如B="AABC"包含两个「A」,而A="ABCD"只包含一个「A」,故返回false. 做题时注意题意,必要时可向面试官确认。
2121

22-
既然不是类似strstr那样的匹配,直接使用两重循环就不太合适了。题目中另外给的条件则是A和B都是全大小单词,理解题意后容易想到的方案就是先遍历A和B统计各字符出现的频次,然后比较频次大小即可。嗯,祭出万能的哈希表。
22+
既然不是类似 strstr 那样的匹配,直接使用两重循环就不太合适了。题目中另外给的条件则是A和B都是全大写单词,理解题意后容易想到的方案就是先遍历 A 和 B 统计各字符出现的频次,然后比较频次大小即可。嗯,祭出万能的哈希表。
2323

2424
### C++
2525

@@ -33,25 +33,18 @@ public:
3333
* else return false
3434
*/
3535
bool compareStrings(string A, string B) {
36-
if (B.empty()) {
37-
return true;
38-
}
39-
if (A.empty()) {
36+
if (A.size() < B.size()) {
4037
return false;
4138
}
4239

4340
const int AlphabetNum = 26;
44-
int freqA[AlphabetNum] = {0};
45-
int freqB[AlphabetNum] = {0};
46-
string::size_type ixA, ixB;
47-
for (ixA = 0; ixA != A.size(); ++ixA) {
48-
++freqA[A[ixA] - 'A'];
49-
}
50-
for (ixB = 0; ixB != B.size(); ++ixB) {
51-
++freqB[B[ixB] - 'A'];
41+
int letterCount[AlphabetNum] = {0};
42+
for (int i = 0; i != A.size(); ++i) {
43+
++letterCount[A[i] - 'A'];
5244
}
53-
for (int i = 0; i != AlphabetNum; ++i) {
54-
if (freqA[i] - freqB[i] < 0) {
45+
for (int i = 0; i != B.size(); ++i) {
46+
--letterCount[B[i] - 'A'];
47+
if (letterCount[B[i] - 'A'] < 0) {
5548
return false;
5649
}
5750
}
@@ -63,48 +56,9 @@ public:
6356

6457
### 源码解析
6558

66-
使用数组`freqA``freqB`分别保存A和B中各字母出现的频次,随后遍历比较两数组,若A中相应的频次小于B时,返回false,否则遍历完后返回true.
67-
68-
最后一步比较`freqA``freqB`的频次时,其实是可以放到遍历B字符串的时候处理的。优化后的代码如下:
69-
70-
### C++
71-
72-
```c++
73-
class Solution {
74-
public:
75-
/**
76-
* @param A: A string includes Upper Case letters
77-
* @param B: A string includes Upper Case letter
78-
* @return: if string A contains all of the characters in B return true
79-
* else return false
80-
*/
81-
bool compareStrings(string A, string B) {
82-
if (B.empty()) {
83-
return true;
84-
}
85-
if (A.empty()) {
86-
return false;
87-
}
88-
89-
const int AlphabetNum = 26;
90-
int freqA[AlphabetNum] = {0};
91-
int freqB[AlphabetNum] = {0};
92-
string::size_type ixA, ixB;
93-
for (ixA = 0; ixA != A.size(); ++ixA) {
94-
++freqA[A[ixA] - 'A'];
95-
}
96-
for (ixB = 0; ixB != B.size(); ++ixB) {
97-
++freqB[B[ixB] - 'A'];
98-
if (freqA[B[ixB] - 'A'] - freqB[B[ixB] - 'A'] < 0) {
99-
return false;
100-
}
101-
}
102-
103-
return true;
104-
}
105-
};
106-
```
59+
1. 异常处理,B 的长度大于 A 时必定返回`false`, 包含了空串的特殊情况。
60+
2. 使用额外的辅助空间,统计各字符的频次。
10761

108-
## Reference
62+
### 复杂度分析
10963

110-
- [Lintcode: Compare Strings - neverlandly - 博客园](http://www.cnblogs.com/EdwardLiu/p/4273817.html)
64+
遍历一次 A 字符串,遍历一次 B 字符串,时间复杂度最坏 $$O(2n)$$, 空间复杂度为 $$O(26)$$.

string/two_strings_are_anagrams.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ O(n) time, O(1) extra space
1616

1717
## 题解
1818

19-
判断两个字符串是否互为变位词,若区分大小写,考虑空白字符时,直接来理解可以认为两个字符串的拥有各不同字符的数量相同。对于比较字符数量的问题常用的方法为遍历两个字符串,统计其中各字符数,若不等则返回`false`. 有很多简单字符串类面试题都是此题的变形题。
19+
判断两个字符串是否互为变位词,若区分大小写,考虑空白字符时,直接来理解可以认为两个字符串的拥有各不同字符的数量相同。对于比较字符数量的问题常用的方法为遍历两个字符串,统计其中各字符出现的频次,若不等则返回`false`. 有很多简单字符串类面试题都是此题的变形题。
2020

2121
### C++
2222

@@ -59,6 +59,9 @@ public:
5959
2. 初始化含有256个字符的计数器数组。
6060
3. 对字符串 s 自增,字符串 t 递减,再次遍历判断`letterCount`数组的值,小于0时返回`false`.
6161

62+
### 复杂度分析
63+
64+
两次遍历字符串,时间复杂度最坏情况下为 $$O(2n)$$, 使用了额外的数组,空间复杂度 $$O(256)$$.
6265
## Reference
6366

6467
- *CC150 Chapter 9.1* 中文版 p109

0 commit comments

Comments
 (0)