Leetcode—最大无重复子串
2016-07-17 11:45
190 查看
题目如下:
求一个字符串的最长无重复子串
Given a string, find the length of the longest
substring without repeating characters.
Examples:
Given "abcabcbb",
the answer is "abc",
which the length is 3.
Given "bbbbb",
the answer is "b",
with the length of 1.
Given "pwwkew",
the answer is "wke",
with the length of 3. Note that the answer must be a substring, "pwke" is
a subsequence and not a substring.
代码如下:
算法思想:
找出字符串中任意两个相同字符串,然后计算它们之间字符的个数,若任意两个相同字符之间间隔的不相同字符越多,则代表它们之间的无重复字符串越多!
在如上的代码中,有两个非常重要的变量
1. start:记录无重复字符串的起始位置
2. map容器记录每个元素上次出现的位置,如果上次出现的位置在start之后,说明从start到当前位置,该元素是第二次出现,如果是这样,那就将当前start的值设置为当前重复元素的上一次出现的位置的值。
3. 每一次for循环都将设置当前位置上元素出现的位置。
。程序从一开设置最长无重复字符串的长度为零,且无重复字符串的下标从0开始,
其中,m[c]>=start代表上次出现的位置如果在无重复字符开始位置的右边(包括=号是因为会出现aaaaa的情况)
4. 这个算法题的关键点在与选取无重复字符的起始点,假设我们有如下字符串
IAMSTAJKMTHL
我们的惯性思维是将IAMST和AJKMT和HL划分为最小的无重复的子串,也就是说我们会从第一个字符开始往前找一旦找到和前面字符一样的话,就将该字符的下一个字符设为无重复字符串的起始点,但这样的做法是不正确的
在上述的例子中
I A M S T A J K
0 1 2 3 4 5 6 7
我们检测到了第5个字符有重复,那么从0到4之间的字符就没有重复,那么下一个无重复字符串的起始点就不可能在[0,1]之间,只能从2开始,因为A和下标为2的前一个元素相同,和[2,4]之间的元素可定不同,所以2可以看作是新不重复子串的起始点。
做如下修改之后就可以求出最长无重复子串的起止位置
求一个字符串的最长无重复子串
Given a string, find the length of the longest
substring without repeating characters.
Examples:
Given "abcabcbb",
the answer is "abc",
which the length is 3.
Given "bbbbb",
the answer is "b",
with the length of 1.
Given "pwwkew",
the answer is "wke",
with the length of 3. Note that the answer must be a substring, "pwke" is
a subsequence and not a substring.
代码如下:
class Solution { public: int lengthOfLongestSubstring(string s) { int ret = 0; map<char, int> m; for (int i = 0; i < 26; i++)m[97 + i] = -1;//每个字符上次出现的位置是-1 int start = 0;//无重复字符开始的位置 for (int i = 0; i < s.length(); i++){ char c = s[i]; if (m[c] >= start){ start = m[c]+1; m[c] = i;//最近一次出现的位置 } else{ m[c] = i;//最近一次出现的位置 ret = max(ret, i - start+1); } } return ret; } };
算法思想:
找出字符串中任意两个相同字符串,然后计算它们之间字符的个数,若任意两个相同字符之间间隔的不相同字符越多,则代表它们之间的无重复字符串越多!
在如上的代码中,有两个非常重要的变量
1. start:记录无重复字符串的起始位置
2. map容器记录每个元素上次出现的位置,如果上次出现的位置在start之后,说明从start到当前位置,该元素是第二次出现,如果是这样,那就将当前start的值设置为当前重复元素的上一次出现的位置的值。
3. 每一次for循环都将设置当前位置上元素出现的位置。
。程序从一开设置最长无重复字符串的长度为零,且无重复字符串的下标从0开始,
其中,m[c]>=start代表上次出现的位置如果在无重复字符开始位置的右边(包括=号是因为会出现aaaaa的情况)
4. 这个算法题的关键点在与选取无重复字符的起始点,假设我们有如下字符串
IAMSTAJKMTHL
我们的惯性思维是将IAMST和AJKMT和HL划分为最小的无重复的子串,也就是说我们会从第一个字符开始往前找一旦找到和前面字符一样的话,就将该字符的下一个字符设为无重复字符串的起始点,但这样的做法是不正确的
在上述的例子中
I A M S T A J K
0 1 2 3 4 5 6 7
我们检测到了第5个字符有重复,那么从0到4之间的字符就没有重复,那么下一个无重复字符串的起始点就不可能在[0,1]之间,只能从2开始,因为A和下标为2的前一个元素相同,和[2,4]之间的元素可定不同,所以2可以看作是新不重复子串的起始点。
做如下修改之后就可以求出最长无重复子串的起止位置
class Solution { public: int lengthOfLongestSubstring(string s) { int ret = 0,temp=0; int begin = -1, end = -1; map<char, int> m; for (int i = 0; i < 26; i++)m[97 + i] = -1; int start = 0;//无重复字符开始的位置 for (int i = 0; i < s.length(); i++){ char c = s[i]; if (m[c] >= start){//若重复出现则大于或等于1 start = m[c]+1; m[c] = i;//最近一次出现的位置 } else{ m[c] = i;//最近一次出现的位置 temp = max(ret, i - start+1); if (temp>ret){ //在这里适当修改可以求出所有满足条件的字符串 begin =start; end = i; } } } return ret; } };
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">个人觉得这个算法一定要熟练掌握,因为在很多字符串算法延伸题中会用到这个子功能,然后再这个子功能上进行下一步拓展等等.........</span>
相关文章推荐
- 数据库链接字符串查询网站
- Flex字符串比较 还有Flex字符串操作
- Ruby中创建字符串的一些技巧小结
- ASP下经常用的字符串等函数参考资料
- 将字符串小写转大写并延时输出的批处理代码
- 将字符串转换成System.Drawing.Color类型的方法
- Lua源码中字符串类型的实现
- Lua性能优化技巧(四):关于字符串
- 字符串聚合函数(去除重复值)
- Ruby中的字符串编写示例
- 总结的5个C#字符串操作方法分享
- sqlserver中求字符串中汉字的个数的sql语句
- sql server字符串非空判断实现方法
- C#算法函数:获取一个字符串中的最大长度的数字
- VBS的字符串及日期操作相关函数
- C#实现将千分位字符串转换成数字的方法
- jquery 删除字符串最后一个字符的方法解析
- PowerShell实现在字符串中查找大写字母
- PowerShell中使用Out-String命令把对象转换成字符串输出的例子
- PowerShell中字符串使用单引号和双引号的区别