本文是个人对LeetCode中字符串类型题目的总结,纯属个人感悟,若有不妥的地方,欢迎指出。
一、有关数字
1、数转换
题Roman to integer这两题是罗马数字和整数之间的相互转换,首先要懂得什么是罗马数字以及相应的组数规则。LeetCode的题中给出的数字最大的是3999,。针对第一题有两种解法:第一是列举出罗马数字在个十百千上的各种情况,形成一个二维矩阵,然后对整数不停的取余、除10来确定相应的罗马数字;第二种是先列出罗马数字组成情况,然后通过从大到小去给定的数字试探。针对第二题,要抓住罗马数的组词规则,然后遍历字符串,若当前值比后一个小,则减去当前值,若不小则加上。
2、计算加、乘
String to integer atoi中前处理一样。第二题要考虑最高位的进位和字符和数字之间的转换。
3、跳过空格
String to integer atoi这题的思路比较简单,就是遍历字符串,保存的结果乘以10加上当前字符对应的数。但有很多需要注意的地方:一是,字符串中的空格问题,若字符串前后有空格,要跳过;二是,字符串中正、负号的问题;三是,字符串的数转换为整数时,可能越界的问题。这里针对越界的问题,有两种解决方法:一是,提升保存结果变量的类型,如变为long long 类;二是,每次乘以10之前先判断是否乘10之后是否会越界。
Length of last word和上面提到的一点要特别注意,从后面开始遍历字符串时,要注意跳过空格。
4、验证数字
二、最长问题
1、最长回文串
题Manacher's Algorithm算法,可以在线性的时间内求出最大回文串的长度,算法的关键在于利用了回文串的特点----关于中心点两边相等。该算法分三步:第一步是,改造给定字符串,通过在字符之间插入特定的字符使字符串的长度是奇数个,同时也使得只要出现回文串在改造后的新字符串中都是奇数个;第二步,明白新回文串和原字符回文串中的关系;第三步,求出新字符串中各个字符所对应的回文串长度。另外维持一个最大长度,这样可以避免再次扫描数组找最大的长度。
2、最长无重复子串
题Longest substring without repeating characters要特别注意的一点是,更新最长无重复子串起点的条件有两条:当前字符在之前出现过,还有,要在起点之后出现过,怎么理解第二点了?恩,如:“adbefghba”,当第二个字符b出现时,start移动到第一个字符b处,但移动到第二字符a时,难道因为a出现过一次,就要将起点移动到第一个字符a?显然不是,所以,出现重复时一定要是在起点之后,才能更新起点。这题最好结合相关代码理解。
3、最长连续序列
Longest consecutive sequence,还是利用hash表的思想,将字符串存入unordered_set中,然后遍历字符串,若某字符在hash表中,然后看该字符的左右是否在hash表中,最后右减左,再减1(因为跳出while循环时,两者都不是和当前字符的相邻)。另外,我们遍历到一个字符的左右时,若是删除了,可避免重复访问,因为若是现在这个字符和之前的某个字符相邻,则之前的字符肯定遍历到了当前字符,所以不必在遍历一遍。
三、字符串匹配
1、两字符串是否匹配
Implement strstr,判断一个是不是另一个的子串,暴力解法是,两字符串对应的字符一个个对比,直到找个匹配的,这样的时间复杂度为O(kn)。关键的点是不匹配时目标函数的下标的返回。这里是通过i+j作为目标函数的下标的方式,即可以保证i不动,但目标通过j 的移动,实现对目标串随对比串的移动;至于KMP算法,就是利用之前对比的信息,来实现快速跳转对比,从而加速对比过程。
2、表达式匹配
Regular expression matching 关键在于当遇到“*”时的处理情况,这里最好用动态规划的方法,好理解一些。当前字符不是*时,只要判断之前对应的是否匹配和当前对应的字符是否匹配即可。当遇到的是*时,*可以代表0个也可代表多个前一个字符,所以要分这两种情况考虑。
Wildcard matching 若当前字符时*,两字符当前对应的位相匹配时,则两者同时向后移动就行,若不匹配则考虑返回上一个*的下一位开始对比,若当前是*,则要记下此时两个字符串中的位置,所以要定义两个指针,用于返回比较。
四、找规律
count and say的单次循环中,当当前字符和前一个不相等时,就将字符的个数和对应的字符存入中间变量中,因为下次的初始值是上一次的结果,所以要用每次的结果去做初始值。
Zigzag conversion关键在于找到竖行和斜行字符对应下标的关系。以每行为单位去进行。
五、哈希 Anagrams以一各个单词取出来,排序以后插入哈希表中,若遇到已存在哈希表中的字符,则将其对应的原字符串存入结果中,但是对于已经存在哈希表中那个字符对应是否存入,要看是否为第一遇到重复的,可以通过设置,已经存入结果的,将其下标设为-1,每次判断已在哈希中的字符串的对应下标和-1的大小来决定。这一题可以为好多这类型的题提供思路,要好好理解。 六、深搜 Palindrome partitioning 深搜的套路要好好理解。