找出字符串中对称的子字符串的最大长度
2015-08-07 23:09
281 查看
闲来无事翻了翻之前的面试书,有一道题勾起了我的兴趣,题目如下:
输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
这道题目的解法挺多。这里介绍一种比较巧妙,同时算法的时间复杂度为O(n^2)级别的算法给大家参考。
算法描述如下:
这个算法的核心思想是扫描整个字符串,从中间的两个字符开始向两边扫描,找出对称字串并记录其长度,最终返回最长的对称字串的长度。
在从中间两个字符向两边扫描寻找对称子串时,有两种情况必须考虑到:一是当对称子串包含奇数个字符时,我们要从当前指针ptr指向字符的前后两个字符开始扫描;二是当对称子串中包含偶数个字符时,我们要从当前指针ptr指向的字符以及它后面的那个字符开始向两边扫描。如图所示:
如图所示,(a)中ptr指向了A3这个字符,以A3这个字符为中心,通过left和right两个指针向前后扫描是否存在对称子串,这里寻找的是包含奇数个字符的对称子串,因为字符A3本身并不在比较之列。left=ptr-1;right=ptr+1;从left和right两指针开始向前后比较。
(b)中ptr也指向了A3这个字符,但是这里要寻找的是包含偶数个字符的对称子串,因此A3和A4都在比较之列,初始化时left=ptr;right=ptr+1;从left和right两指针开始向前后比较。
整个算法中我们使用指针ptr作为标尺,用ptr遍历整个字符串,每访问到一个字符时,就按照上述两种情况设置指针left和right,并以此为中心向前后扫描搜索对称子串。
每搜索到一个对称子串后就将其长度right-left-1记录下来,并与之前计算出的最大长度maxLength(初始化为0)做比较,如果right-left-1〉maxlength,则将maxLength更新,否则保持不变。最终返回的maxLength即为字符串中最长对称子串的长度。
应用上述算法计算几个字符串的对称子串的最大长度,结果如下:
计算字符串“google”的对称子串的最大长度(对称子串包含偶数个字符)为4
计算字符串“abcasdsatt”的对称子串的最大长度(对称子串包含奇数个字符)为5
输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
这道题目的解法挺多。这里介绍一种比较巧妙,同时算法的时间复杂度为O(n^2)级别的算法给大家参考。
算法描述如下:
int GetLongestSymmetricalSubStrLength(char* str) { int maxLength = 0; char* ptr = str; int newLength; while(*ptr != '\0') { /*考虑子串是奇数个的情况*/ char* left = ptr - 1; char* right = ptr + 1; while(left >= str && *right != '\0' && *left == *right) { left--; /*从left和right向两边扫描,直到出现不相等的元素或者某一端到头了 */ right++; } newLength = right - left - 1; /*退出while循环时,此时*left != *right,计算子串的长度*/ if(newLength > maxLength) { maxLength = newLength; /*如果大于maxLength则更新它*/ } /*考虑子串是偶数个的情况*/ left = ptr; right = ptr + 1; while(left >= str && *right != '\0' && *left == *right) { left--; right++; } newLength = right - left - 1; /*退出while循环时,此时*left != *right,计算子串的长度*/ if(newLength > maxLength) { maxLength = newLength; } ptr++; } return maxLength; }
这个算法的核心思想是扫描整个字符串,从中间的两个字符开始向两边扫描,找出对称字串并记录其长度,最终返回最长的对称字串的长度。
在从中间两个字符向两边扫描寻找对称子串时,有两种情况必须考虑到:一是当对称子串包含奇数个字符时,我们要从当前指针ptr指向字符的前后两个字符开始扫描;二是当对称子串中包含偶数个字符时,我们要从当前指针ptr指向的字符以及它后面的那个字符开始向两边扫描。如图所示:
如图所示,(a)中ptr指向了A3这个字符,以A3这个字符为中心,通过left和right两个指针向前后扫描是否存在对称子串,这里寻找的是包含奇数个字符的对称子串,因为字符A3本身并不在比较之列。left=ptr-1;right=ptr+1;从left和right两指针开始向前后比较。
(b)中ptr也指向了A3这个字符,但是这里要寻找的是包含偶数个字符的对称子串,因此A3和A4都在比较之列,初始化时left=ptr;right=ptr+1;从left和right两指针开始向前后比较。
整个算法中我们使用指针ptr作为标尺,用ptr遍历整个字符串,每访问到一个字符时,就按照上述两种情况设置指针left和right,并以此为中心向前后扫描搜索对称子串。
每搜索到一个对称子串后就将其长度right-left-1记录下来,并与之前计算出的最大长度maxLength(初始化为0)做比较,如果right-left-1〉maxlength,则将maxLength更新,否则保持不变。最终返回的maxLength即为字符串中最长对称子串的长度。
应用上述算法计算几个字符串的对称子串的最大长度,结果如下:
计算字符串“google”的对称子串的最大长度(对称子串包含偶数个字符)为4
计算字符串“abcasdsatt”的对称子串的最大长度(对称子串包含奇数个字符)为5
相关文章推荐
- 我们90后的爱情
- C#之正则表达式验证
- svn常用命令
- 2015 ACM多校训练第一场
- ACM 计算几何模板 点在三角形内
- hdu 5358 First One (尺取法)
- [leedcode 222] Count Complete Tree Nodes
- sed 常用方法 脚本范例
- 装饰器模式,代理模式
- Python实用入门
- 第79讲:单例深入讲解及单例背后的链式表达式
- Linux下Debug模式启动Tomcat进行远程调试
- android 百度地图坐标类型setCoorType
- uva uva 565 - Pizza Anyone?
- 计算Java List中的重复项出现次数【转】
- 2015年浙江省职工职业技能大赛暨全国大赛选拔赛计算机程序设计员
- BZOJ2924 : [Poi1998]Flat broken lines
- 把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,不能申请额外的空间
- basename()—众里寻他千百度,那人却在linux函数库
- C++中overload,override,overwrite的区别详细解析