刷题时间: 2019/04/08 – 2019/04/13
主播:yxc(闫学灿)
视频链接:https://www.bilibili.com/video/av35164027?from=search&seid=5284571979100115908
解题心得
No.93 打印所有合法的IP (AC)
- 首先特判字符串长度小于4和大于12的不合法情况;
- 每个字段后面加‘.’,最后添加到答案中是,去掉最后一个’.’。
- 需要特判不合法的写法,如01.00.010.10,含多余的0的也是不合法的表达,去掉。
- 深度递归来做。
No.43 字符串乘法 (AC)
- 题意:两个超大的数用字符串表示,求他们的成绩。
- 此题先要放弃转换成整数之后再求解的方法,直接模拟竖式计算。
- 先计算按位乘法,将中间结果以string的形式存在vector数组中,然后对所有的中间结果做加法计算。
- 有几点容易出错:
int tmp = p % 10 + up; s.insert(0, to_string(tmp % 10)); // tmp有可能还超过10,需要再对10取模
int l = pool[j].size(); if (l > i){ sum += (pool[j][l - i - 1] - '0') ; // 只有当长度够的时候才参与运算 }
No.49 把单词组成字母相同的分为一组(AC)
- 哈希表来做
unordered_map<string, vector<string> > hash;
- 把每个单词按照字典序排序
string s; sort(s.begin(), e.end());
- 然后把字典序排序相同的放到同一个hash值对应的
vector< string >
中 - 遍历哈希表
for(auto group : hash)
, 将哈希值中对应的全部string放到结果中res.push_back(group.second);
No.151 翻转字符串,并保持单词内部顺序不变(AC)
- 翻转两次,第一次翻转整个句子,第二次翻转每个单词
string
整个句子翻转直接用reverse(s.begin(), s.end());
单词内部翻转用reverse(s.begin() +i, s.begin() + j);
i,j分别指向单词的第一个和最后一个字符。- 题目还要求删除多余空格,用
s.erase(s.begin() + i);
- 需要注意的是,除最外层循环需要判断
j < len && s[j] != '\0'
,如果漏掉j < len,会导致无法跳出循环 ;初始设置i = j = 0
,那么初始判断是应保证i <= j
,若没有=
,则循环无法进入。 - 最后一个单词翻转可能会有一盒对于空格,需特判一下。删除用
s.erase(s.begin() + s.size() - 1)
,s.erase(s.end() - 1)
是不对的!
No.165 判断版本号是否相同(AC)
- 可以把版本号(
string
)转换成一个vector<int>
数组 vector<int>
可以直接比较,比较的时候是按照字典序比价的。vector<int> v1; vector<int> v2; if(v1 > v2) ...;
No. 5 求最长回文子串(AC)
- 仍然按照加‘#’的方法解决就问题,代码中需要考虑的边界条件比较多,很容易写溢出。
- 直接分奇偶两种情况来算最长的长度,这种方法写起来更简洁。
No.3 求最长无重复字符的子串(AC)
- 直接枚举,两层循环
No.131 回文子串划分(待完成!)
- 。。。TODO。。。
No. 227 多项式计算(不包含括号)(AC)
- 需要用栈来做
- 两个栈,一个存储数字,一个存储运算符
- 在实现的时候有一些技巧。按照自己的方法来实现,思路不清晰,且容易出错,详见链接。参考yxc代码,每一次循环的时候,只有碰到数字,采取判断要不要执行运算,这样很好避免了运算符后面没有数字的情况。但也有边界情况需要判定,当数字栈中只有一个元素,且符号栈中没有元素时,不能直接访问ops.top()。
- 空格字符需要过滤
- 当符号站中是两个加减符号时,自己写的方式是计算后两个数的加减运算,这样会导致最后有一步加减运算无法被执行。yxc的代码中原则的是计算前两个数的加减运算,再把另一次加减运算压入栈。
- 要有一个实现的小技巧,为了保证多项式中每一步都能被执行,在多像是末尾加上“+0”。
- 枚举指针要及时更新
- 把string转换成数字。
atoi(s.substr(i, j - i).c_str())
。atoi()
需要传入char*,因此string在传入之前还要进行一下转化s.c_str()
.
No.224 含括号的加减运算(AC)
- 同上,用两个栈分别存储数字和运算符。
- 不需要在字符串后面“+0”
- 当前指向的字符为 ‘)’ 时需要特殊处理。和 ‘)’ 挨着的一定是 ‘(’ ,因此先将它弹出来,弹出来之后再判断栈中是否还有 ‘+’ / ‘-’ 运算符,如果有,进行计算。
- 最后返回数字栈栈顶元素
- 这类题目需要多分析几个样例,找到模拟规律,不然容易漏掉某些处理
- 由于只有加减运算,因此可以从前往后过滤掉括号,直接按顺序计算。
No.647 求字符串中回文子串的数目 (AC) (划重点)
- 本题可以用两种方法来做,分别是中心拓展法和字符串哈希。
- 中心扩展法会遇到的一个问题是有奇偶两种情况需要分别考虑。这里不能采取加‘#’将所有情况转换成奇数的策略,这样会直接影响结果,需要奇偶分开讨论。
- 字符串哈希算法有几个需要注意的点,首先需要记录正序和逆序的前缀哈希值;其次,哈希值一般是采用下标从1–len, 因此在 计算哈希值时需要特别要注意一下;在计算某个字符串的哈希值时,也要特别注意下标,由于前缀哈希值的下标是从1–len, 因此,若不对应,容易溢出。
No.438 Find All Anagrams in a String (TLE)(划重点)
- TLE思路: 将字符串按字典序排序,判断是否相等。超时
No.8 将字符串转换成数字 (AC)
- 考虑到各种边界情况(如超出int范围的数据,sum可以定义为long类型)
- 用一个symbol变量记录数字的符号
- 用flag变量就是否已经开始计数
- 返回答案是记得sum * symbol
No. 判断一个含无效字符的字符串是否为回文串 (AC)
- 方法一,遍历去掉无效字符后,将结果字符串翻转,比较反转前后的字符串是否相等。
- 方法一的做法时间效率不高
- 用线性扫描的方法优化,双指针实现。
- 需要注意的是,如何判断前后两个字符可以等效。当时大写字母和数字的组合时,直接用
abs(s[i] - s[j]) == 32;
判断会出Bug,还需要加上is_character(s[i]) && is_character(s[j])
的限制条件。
附: