Longest Substring Without Repeating Characters

题目网址:Longest Substring Without Repeating Characters

题目解析:这题我写了很久,刚开始写的时候思考的不全面,只想到了用set集合保存已经扫描到的元素,利用一个for循环来访问所有的元素,判断钙元素是否出现在set中,如果不出现,那么我就ans++,最后找到最大的ans;如果存在,那么我就把set集合置空(这里就不对了,因为如果是abca,最后求得的长度最大是3,但是如果对pwabwef这个答案应该是5,但结果出来确是4,原因在于我在发现下一个字符属于set集合的时候,我就把set集合置空,且ans清零,重新开始计数,这样我缺失了对于a和b的统计);

方法一:

后来我就想不要清空set,而是采用两个下标i和j(j是子串尾,i子串头),每次不在set里面j++,ans=max(ans,j-i),如果在set里面,我就不断的i++,并在set里面清除i下标元素(直到是set里面没有这个s[j])

方法二:

但是方法一就需要从i位置不断的++删除元素,直到发现set里面没有s[j],这样很麻烦,那么我们可以通过map来直接的控制这个。map<char,int>:表示字符s[j]与下标j之间的关系。设置i=0,j=0,如果不在map里面,我就j++,如果在map里面,我更新i不需要不断的++得到,只需要找到s[j]与j下标的映射就行,直接得到。

方法三:直接使用hash表,大致根使用map是一致的思想。

/*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.

*/

#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
/*class Solution {//time limit exceeded,暴力搜索方法对每一个子串判断是否存在重复元素即可
public:
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		int ans = 0;
		for (int i = 0; i < len; i++){
			for (int j = i + 1; j <= len; j++){
				if (isok(s, i, j))
					ans = max(ans, j - i);
			}
		}
		return ans;
	}
	bool isok(string s, int start, int end){
		set<char> ss;
		for (int i = start; i < end; i++){
			if (ss.find(s[i])!=ss.end()){
				return false;
			}
			ss.insert(s[i]);
		}
		return true;
	}
};*/
/*class Solution {//方法一:时间复杂度:O(2*n)=O(n)
public:
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		set<char> ss;
		int ans = 0, i = 0, j = 0;
		while (i < len&&j < len){
			if (ss.find(s[j]) == ss.end()){
				ss.insert(s[j++]);
				ans = max(ans, j - i);
			}
			else{
				ss.erase(s[i++]);
			}
		}
		return ans;
	}
};*/
/*class Solution {//方法二:时间复杂度:O(n)
public:
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		int ans = 0;
		map<char, int> m;
		for (int j = 0, i = 0; j < len; j++){
			if (m.find(s[j]) != m.end()){
				i = max(m.find(s[j])->second, i);
				//cout <<" i:"<< m.at(s[j]) << endl;
			}
			ans = max(ans, j - i + 1);
			//m.insert(make_pair(s[j], j + 1));如果这里是这句话就会出错,因为如果map已经存在这个s[j]与j的映射的话,这句话就不会执行,所以我需要下面这个。
			m[s[j]] = j + 1;
			//cout << "j+1" << j + 1 << endl;
			//cout << "ans"<<ans << endl;
		}
		return ans;
	}
};*/
class Solution {//方法二的改进:算法时间缩短了,主要是因为添加了else操作
public:
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		int ans = 0;
		map<char, int> m;
		for (int j = 0, i = 0; j < len; j++){
			if (m.find(s[j]) != m.end()){
				i = max(m.find(s[j])->second, i);
				//cout <<" i:"<< m.at(s[j]) << endl;
				m[s[j]] = j + 1;
			}
			else{
				m.insert(make_pair(s[j], j + 1));
			}
			ans = max(ans, j - i + 1);
			//cout << "j+1" << j + 1 << endl;
			//cout << "ans"<<ans << endl;
		}
		return ans;
	}
};
class Solution {//方法三:
public://明明可以通过,但是却不行,不知道问题出现在哪里。。。。
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		int ans = 0;
		int *index = new int[128];
		for (int j = 0, i = 0; j < len; j++){
			i = max(index[s[j]], i);
			ans = max(ans, j - i + 1);
			index[s[j]] = j + 1;
			//cout << ans << endl;
		}
		return ans;
	}
};
int main()
{
	string str;
	while (cin >> str){
		Solution s;
		cout << s.lengthOfLongestSubstring(str) << endl;
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值