不重复字符的最长子串

leetcode:3. 无重复字符的最长子串

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

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

总结:使用滑动窗口来做,保存一个数组,当做哈希表。每次遍历的时候,先把当前字符添加到哈希表中,如果出现次数为1,则表明它是刚刚添加进去的,此时不断的扩充子串word长度,一旦超过max_len,就替换;否则出现次数为2次,这时候进行一个循环,窗口向右滑动,直到指向重复那个数,abcdc c出现重复,窗口左侧begin = 0开始向右滑动,滑动到b,还是重复,滑动到c,还是重复,滑动到d的时候,发现已经不重复,此时begin=3。另外为什么不用保存窗口中出现重复的子串长度?因为一旦出现了重复,begin起码要移动一位,或者更多位,所以这时候的子串长度肯定小于等于前一个没重复子串长度,而每一个子串长度的最大值都已经保存了,所以不用保存。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(!s.size())   return 0;
        char c_num[128] = {0};
        int max_len = 0;
        string word;
        int begin = 0;
        for(int i =0;i<s.size();i++){
            c_num[s[i]]++;
            if(c_num[s[i]] == 1){
                word += s[i];
                if(max_len < word.size())   max_len =  word.size();
            }
            else{
                while(begin < i && c_num[s[i]] > 1){
                    c_num[s[begin]]--;
                    begin++;
                }
                word = string(s.begin()+begin,s.begin()+i+1);
            }
        }
        return max_len;
    }
};

最后:其实这里定义哈希数组是char类型,里面存放的是'0'应该,但是判断是否出现的时候用的是(c_num[s[i]] == 1),字符类型的'1'怎么会跟整型1相等呢?但是可以过OJ,如果写的时候还是开辟成整型数组好了,看看以后能不能想到如何解决。并且就算用int型大小也只有512B,也是一个O(1)空间复杂度。

------>char是一个1B,但是有8位,可以表示的整数最大为255.计算机存储的时候不管是几进制都是按2进制存储,所以这些数字可以被8位表示出来就能存进来。

滑动窗口直接解决

class Solution {
public:
	int lengthOfLongestSubstring(string s) {
		if (!s.size())   return 0;
		int c_num[128] = { 0 };
		int begin = 0;
		int maxlen = 0, curlen = 0;
		for (int i = 0; i < s.size(); i++) {
			char c = s[i];
			c_num[c]++;
			if (c_num[c] == 1) {
				curlen = i - begin+1;
				maxlen = max(curlen, maxlen);
			}
			else {
				while (c_num[c] > 1) {
					c_num[s[begin]]--;
					begin++;
				}
			}
		}
		return maxlen;
	}
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值