3. Longest Substring Without Repeating Characters

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.

Subscribe to see which companies asked this question.

题解:这到题的最优解肯定是O(n),理论是这样的,我的解法接近于O(n),但是相比于最优解还是差一点;讲一下我的思路:将字符串从头到尾遍历一遍,遍历的过程中,使用无序图unordered_map <char,int>,关键值是char,int是该char字符遍历到i为止的最新位置;和起始start,标记当前无重复子字符串起始位置,初始值当然是0。当遍历到map中已经存在该字符char时,首先检查现在无重复字符串的长度与max的大小,决定是否对max重新赋值;然后再确定start的值,start要满足一个条件,新的start必需要比旧start大,因为,我们新检查到的重复的char,有可能是在start前面的,比如abba,当遍历到第是s[2] = b时,我们发现map中已经存在<b,1>,那么,start会等于s[1]的后面一个点,即start = 2;max = 2;此时map中存在<a,0><b,2>,当遍历s[3] = a时,但是此时检查到的重复a的位置是0,比start还小;如果从0位置开始计数,没有意义,因为a已经是ab无重复子字符串的一部分,所以start 还是 2;再者就是start的赋值,因为start是从重复的字符后面一个算起的,所以start 可以=it->second +1 也可以=ls[s[i]] +1 ;说一下可以优化的地方吧,总感觉it = ls.find(s[i]).可以用某种方法代替,因为ls[s[i]]+1 可以代替it->second +1 就没有使用map的必要,好吧用数组;

解法一:

class Solution {
public:
  int lengthOfLongestSubstring(string s) {
	int i;
	int max = 0;
	int start = 0;
	unordered_map<char,int> ls;
	unordered_map<char, int>::iterator it;
    for( i = 0; i < s.size();i++) {
		it = ls.find(s[i]);
	    if(it != ls.end()){
			max = max > i - start ? max : i - start;
			start = start > (it->second + 1) ? start : it->second + 1;
		}
        ls[s[i]] = i;
	}
	max = max>i - start ? max : i - start;
	return max;
  }
};


结果如下:
优化
class Solution {
public:
  int lengthOfLongestSubstring(string s) {
	int i;
	int max = 0;
	int start = 0;
	vector<int> ls(256,-1);
    for( i = 0; i < s.size();i++) {
	    if(ls[s[i]] != -1 &&  (ls[s[i]] + 1)>start){
			max = max > i - start ? max : i - start;
			start = ls[s[i]] + 1;
		}
        ls[s[i]] = i;
	}
	max = max>i - start ? max : i - start;
	return max;
  }
};

结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值