每日一题做题记录,参考官方和三叶的题解 |
题目要求
思路:模拟
构建一个哈希表存单词和出现的次数,注意把禁用词直接排除掉不计入。
Java
class Solution {
public String mostCommonWord(String paragraph, String[] banned) {
Set<String> ban = new HashSet<>(); //禁用词
for(String b : banned)
ban.add(b);
char[] cs = paragraph.toCharArray();
int n = cs.length;
String res = null;
Map<String, Integer> map = new HashMap<>(); //记录单词与出现次数
for(int i = 0; i < n; ) {
if(!Character.isLetter(cs[i]) && ++i >= 0) //跳过空格标点等非字母元素
continue;
int j = i;
while(j < n && Character.isLetter(cs[j])) //获取当前单词
j++;
String sub = paragraph.substring(i, j).toLowerCase(); //转小写
i = j + 1;
if(ban.contains(sub))
continue;
map.put(sub, map.getOrDefault(sub, 0) + 1); //计数加一
if(res == null || map.get(sub) > map.get(res)) //更新答案
res = sub;
}
return res;
}
}
- 时间复杂度: O ( n + m ) O(n+m) O(n+m),遍历 p a r a g r a p h paragraph paragraph的 n n n位和 b a n n e d banned banned的 m m m位。
- 空间复杂度:
O
(
n
+
m
)
O(n+m)
O(n+m),用来存禁用词的
b
a
n
ban
ban长度为
m
m
m,用来存单词计数的哈希表
m
a
p
map
map长度最大为
n
n
n,还有个
p
a
r
a
g
r
a
h
paragrah
paragrah的
toCharArray
长度为 n n n(可不用)。
C++
和Java区别不大,但有一个点(昨天也是)——C++的取子串两个参数分别是起始点和长度,而不是Java的起点和终点。
class Solution {
public:
string mostCommonWord(string paragraph, vector<string>& banned) {
int n = paragraph.size();
string res = "";
unordered_map<string, int> map; //记录单词与出现次数
transform(paragraph.begin(), paragraph.end(), paragraph.begin(), ::tolower); //转小写
for(int i = 0; i < n; ) {
if(!isalpha(paragraph[i]) && ++i >= 0) //跳过空格标点等非字母元素
continue;
int j = i;
while(j < n && isalpha(paragraph[j])) //获取当前单词
j++;
string sub = paragraph.substr(i, j - i);
i = j + 1;
if(count(banned.begin(), banned.end(), sub))
continue;
map[sub]++; //计数加一
if(res == "" || map[sub] > map[res]) //更新答案
res = sub;
}
return res;
}
};
- 时间复杂度: O ( n + m ) O(n+m) O(n+m),遍历 p a r a g r a p h paragraph paragraph的 n n n位和 b a n n e d banned banned的 m m m位。
- 空间复杂度: O ( n + m ) O(n+m) O(n+m),用来存禁用词的 b a n ban ban长度为 m m m,用来存单词计数的哈希表 m a p map map长度最大为 n n n。
转小写/大写的几种方法
方法 | 功能 |
---|---|
tolower(c) | 将单个字符 c c c转为小写 |
toupper(c) | 将单个字符 c c c转为大写 |
strlwr(str) | 将字符串 s t r str str转为小写,返回指向 s t r str str的指针 |
strupr(str) | 将字符串 s t r str str转为大写,返回指向 s t r str str的指针 |
transform(begin, end, res, opration) | 将起始迭代器
b
e
g
i
n
begin
begin和结尾迭代器
e
n
d
end
end中间的字符按
o
p
r
a
t
i
o
n
opration
opration处命令进行转换,将结果存至
r
e
s
res
res,转大写为::toupper 、转小写为::tolower |
P.S.transform
函数还有很多用法,在此不详述,可参考这里
总结
这一周似乎天天都在模拟,管他什么题直接模拟……感觉人都要变傻了。
欢迎指正与讨论! |