最长不含重复字符的子字符串(剑指offer-48)

1、题目描述

    找出一个字符序列中一个最长的包含不重复字符的子字符串,比如在字符串“arabcacfr”中,最长的不含重复字符的子字符串是“acfr”,长度为4。

2、解题思路

(1)暴力破解

    使用暴力法可以在O(n^2)的时间复杂度内找到字符序列的所有字符串,然后在O(n)的时间复杂度内比较这个字符串是否包含重复字符,因为暴力解的时间复杂度为O(n^3),如果面试用暴力解,基本上就凉凉了。

(2)使用滑动窗口

    从头到尾遍历数组元素时,使用一个辅助字典来保存已经找到的元素次数。同时使用一个pos变量来保存滑动窗口的起始位置,用一个变量temp_len来保存滑动窗口的大小,用变量start保存最后所求的窗口的起始位置,用变量max_len来保存窗口的最大长度。遍历过程中,如果这个元素在map中没有出现过,则这个元素在map中的次数设为1,同时计算滑动窗口temp_len的大小,如果滑动窗口temp_len比最大窗口max_len大,则把max_len=temp_len,同时start=pos。如果这个元素在map中已经出现过,那么start指针往后移动到重复元素的下一个元素,移动中划过的元素在map中的次数设置为0,时间复杂度O(n^2)。详细代码如下:

#include<iostream>
#include<vector>
#include<map>
using namespace std;

//找出最长不含重复字符的子字符串
void MaxNorepeatSeq(vector<char> input) {
	map<char, int> has_found_char;
	int pos = 0;                   //保存滑动窗口的起始位置
	int max_len = 1;               //保存最终所求的窗口大小
	int temp_len = 1;              //保存滑动窗口的临时大小
	int start = 0;                 //保存最终所求滑动窗口的起始位置
	has_found_char[input[0]] = 1;  //保存已经找到的数组中连续元素的次数
	for (int i = 1; i < input.size(); i++) {
		if (has_found_char[input[i]] == 0) {
			has_found_char[input[i]] = 1;
			temp_len = i - pos + 1;
			if (max_len <= temp_len) {
				max_len = temp_len;
				start = pos;
			}
		}
		else {
			has_found_char[input[i]]++;
			while (has_found_char[input[pos]] != 2 && pos < i) {
				has_found_char[input[pos]] = 0;
				pos++;
			}
			pos++;
			has_found_char[input[i]] = 1;
		}	
	}
	cout << "start:" << start << endl;
	cout << "max_len:" << max_len << endl;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值