3、无重复字符的最长子串

22 篇文章 0 订阅
20 篇文章 0 订阅

题目要求:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

输入: "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

方法一:暴力法 时间复杂度O(n^3) 空间复杂度O(min(m, n)) 超出时间限制

思路:

【1】以长度length为for循环进行截取字符串​ for(int i=length;i>0;i--)

【2】对于截取的字符串进行判断,若无重复字符则返回当前长度​

//判断字符串有无重复部分
 bool isRepeat(string str) {
	 set<char> s;
	 for (int i = 0;i < str.length();++i) {
		 char ch = str[i];
		 //有重复部分
		 if (s.find(ch) != s.end()) {
			 return true;
		 }
		 s.insert(ch);
	 }

	 return false;
 }


 int lengthOfLongestSubstring(string s) {
	 int length; //截取长度
	 for (length = s.length();length > 0;length--) {
		 //index为截取开始位置
		 for (int index = 0;index <= s.length() - length;++index) {
			 string str = s.substr(index, length);
			 if (!isRepeat(str)) {
				 return length;
			 }
		 }
	 }
	 return 0;
 }

方法二:滑动窗口 时间复杂度O(n),空间复杂度O(min(m, n))//n为字符串的大小,m为字符集的大小

思路:

【1】如果从索引 i 到 j - 1 之间的子字符串 s(i,j-1​) 已经被检查为没有重复字符。我们只需要检查 s_j 对应的字符是否已经存在于子字符串 s(i,j-1)​ 中。​

【2】用hashMap记录字符及其下标,​未出现重复字符则将其添加到hashMap中。

【3】若出现重复字符则计算开始位置begin的下标,当前长度currLen为index-begin+1。并更新重复字符的下标

​int lengthOfLongestSubstring(string s) {
	if (s.length() <= 1)
		return s.length();
	unordered_map<char, int> hashMap;
	int max = -1, begin = 0, index = 0, currLen = 0; //begin为无重复字符串开始位置
	for (;index < s.length();++index) {
		char ch = s[index];
		//未出现重复的字符
		if (hashMap.find(ch) == hashMap.end()) {
			hashMap.insert({ ch,index });
		}
		else {	
			int temp = hashMap[ch]+1;	//出现重复字符的下一个下标
			begin = begin > temp ? begin : temp;	//开始位置为较大的位置
			hashMap[ch] = index;
		}
		currLen = index - begin + 1;	//现有长度
		max = max > currLen ? max : currLen;
	}
	return max;
}

对于开始位置begin选择较大位置的说明

例:字符串"twswqpt",当遍历到第二个w时,begin将等于重复字符下一个字符的下标,即s的下标(2)。begin=2

之后遍历到第二个t时,如果没有选择较大位置的begin,begin将等于第一个t后一个字符的下标,即第一个w的下标(1),

显然这是错误的,因为begin等于1的话,字符串中w就重复了。所以要比较begin和temp的大小,选择较大的位置。

最后贴出leetcode中关于本题的讲解

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值