符串的最长无重复字符的子串长度

题目描述:

对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度。

给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度。保证A中字符全部为小写英文字符,且长度小于等于500。

测试样例:

"abcdbefgdchi",12
返回:8

这个题我研究了好半天,确实不好想,看了别人的思路,半天才把代码写出来

分析:

首先定义三个辅助变量:

max_len:表示字符串中最长无重复字符的子串长度,也就是函数返回值

map<char, int>:用来存放当字符串前位置的字符最近出现的位置

pre_len:用来存放当前位置之前最长无重复字符的子串长度

下面开始主逻辑

从字符串的起始处开始遍历

如果map中没有该字符,则将该字符及其下标插入到map中,并将pre_len++

再和max_len进行比较,取较大者赋给max_len

如果map中已经有了该字符,那么取出该字符对应的值(也就是该字符最近出现的下标)记为pos_A

当前下标减去pre_len记为pos_B,表示前面最长无重复字符子串的其实位置

这时候,pos_A和pos_B会有一下三种情况:

第一种情况:posA == pos_B

第二种情况:pos_A > pos_B

第三种情况:pos_A < pos_B

对于第一种情况来说,pre_len 大小不会改变。

对于第二种情况来说,pos_A 在 pos_B的右边,根据 pos_A 和 pos_B 所代表的含义可知道:

在距离当前很近的位置上,当前字符已经出现了重复,因此当前位置之前最长无重复字符子串的长度缩短了,如图所示:

因此,更新后的 pre_len 应该为 当前位置的下标减去 pos_A

对于第三种情况来说,pos_A 在 pos_B 的左边,根据 pos_A 和 pos_B 所代表的含义可知道:

在距离当前很远的位置上,当前字符出现了重复,这个位置比pos_B 还远,这么远的路径上,pos_B 处的字符早已出现了重复,因此当前位置之前最长无重复字符子串的长度应该为 当前位置到pos_A 的距离,如图所示

因此,更新后的 pre_len 应该为 当前位置的下标减去 pos_B + 1

更新后的pre_len 与max_len 进行比较,取其大者即可

注意,最后应该将map中当前位置字符的下标进行更新(千万不能漏掉)



于是乎一个完整的逻辑已经完成了,这样从头到尾遍历这个字符串,最终便可得到

字符串的最长无重复字符的子串长度 max_len


甚至还可以获得该字串,将其单独打印出来(这里留给读者自行实现,不难)


代码如下:

int longestSubstring(string A, int n) {
	if (A.size() <= 0 || n <= 0)
		return 0;

	int max_len = -1;
	int pre_len = 0;
	map<char, int> m;
	for (int i = 0; i < A.size(); ++i){
		if (m.count(A[i]) == 0){
			m.insert(pair<char, int>(A[i], i)); //map中不存在该字符,则直接插入
			++pre_len;
			if (pre_len > max_len)
				max_len = pre_len;
			continue;
		}

		map<char, int>::iterator iter_prev = m.find(A[i]);
		int pos_A = iter_prev->second;
		int pos_B = i - pre_len;

		if (pos_A > pos_B)
		{
			pre_len = i - pos_A;
		}
		else if (pos_B > pos_A)  //pos_A <= pos_B
		{
			pre_len = i - pos_B + 1;
		}
		else
		{
			//do nothing!
		}

		if (pre_len > max_len)
			max_len = pre_len;

		m[A[i]] = i;  //更新map
	}

	return max_len;
}

现在是 2016.9.3/1:30 时候不早了,睡觉了,晚安!

时间: 2024-10-05 03:59:48

符串的最长无重复字符的子串长度的相关文章

lintcode 中等题:longest substring without repeating characters 最长无重复字符的子串

题目 最长无重复字符的子串给定一个字符串,请找出其中无重复字符的最长子字符串. 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3. 对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1. 解题 利用HashMap,map中不存在就一直加入,存在的时候,找到相同字符的位置,情况map,更改下标 public class Solution { /** * @param s: a s

[LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++语言 java语言实现

Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. Example 2: Input: "bbbbb" Output: 1 Explana

[LeetCode] 3. Longest Substring Without Repeating Characters 最长无重复字符的子串

1.暴力法: 本题让求给定字符串的最长的无重复字符的子串,首先想到暴力解法,穷举出字符串的所有子串,并判断每个子串是否是不重复子串,具体使用hashset或set判是否有重复字符:暴力法效率很差,时间O(n^3),空间O(n);参考代码如下: 1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s){ 4 int res = 0; 5 const int size = s.size(); 6 if(s.empty(

[LeetCode]3. Longest Substring Without Repeating Characters寻找最长无重复字符的子串

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest subst

查找字符串中最长无重复字符的子串

设定一个当前子字符串:tempString 设定一个保持最长无重复子串的数组:list 思路: 从第一个字符开始判断, 如果当前子串不包括当前的字符,则当前子串加入当前的字符成为新的当前子串, 如果当前子串包括当前的字符,判断当前字符在当前字符串中的位置,根据这个位置把字符串分成两个字符串,如果后面一个末尾加当前字符为新的当前子字符串,判断当前子串跟list数组中的子串长度,如果当前子串长,则清空list,把当前子串加入:如果相等,直接将当前子串加入list. 最后list的中的子字符串就是最长

LintCode-最长无重复字符的子串

给定一个字符串,请找出其中无重复字符的最长子字符串. 样例 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3. 对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1. 挑战 O(n) 时间 分析:遍历该字符串,每遍历一个字母时,利用map去找该字母最近一次出现是什么时候,中间这一段便是无重复字符的字符串. 代码: class Solution { public: /** * @

字符串练习(八):最长无重复字符子串

对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度. 给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度.保证A中字符全部为小写英文字符,且长度小于等于500. 测试样例: "aabcb",5 返回:3 public class DistinctSubstring { public int longestSubstring(String A, int n) { // write code here if(A==null || n==0){ return

算法--最长无重复字符子串

转载请标明出处http://www.cnblogs.com/haozhengfei/p/d0906ebc98f7b6eaecb3ecd738dc78ac.html 最长无重复字符子串练习题 最长无重复字符子串练习 第12节 最长无重复字符子串练习题 对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度. 给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度.保证A中字符全部为小写英文字符,且长度小于等于500. 测试样例: "aabcb",5 返回:3 J

求字符串的最长无重复字符子串长度

题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wk