leetcode159 至多包含两个不同字符的最长子串

 方法一:

int lengthOfLongestSubstringTwoDistinct(string s) {
	unordered_map<char, int> sHT;	    //滑动窗口的哈希表
                                        //key值为所包含的字符,value值为出现的次数
	int left = 0, right = 0, L = 0,hTsize=0,sLength=s.length();	
    //左右边界指针,子串长度,哈希表大小,字符串长度
	sHT[s[0]]++;

	while (right < sLength) {
		hTsize = sHT.size();
		if (hTsize <= 2) {
			L = max(L, right - left + 1);
			if (right + 1 < sLength) {
				sHT[s[++right]]++;
			}
			else {
				break;
			}
		}
		else {
			if (sHT[s[left]] == 1) {
				sHT.erase(s[left]);
			}
			else if(sHT[s[left]] > 1){
				sHT[s[left]]--;
			}
			left++;
		}
	}

	return L;
}

 

方法二:

int lengthOfLongestSubstringTwoDistinct(string s) {
    int strLength = s.length();
    if (strLength < 3) return strLength;
    int left = 0;
    int right = 0;
    unordered_map<char, int> map;  //key为字符,value为其出现的下标

    int maxLen = 2;

    while (right < strLength) {
        map[s[right]] = right;     //将右边界的字符放入滑动窗口中,并存储其自身及其下标与哈希表中
        right++;
        if (map.size() > 2) {      //滑动窗口内字符多于2个,左边界收缩
                                   //且不是简单地+1,所以时间效率更高!!!!
            unordered_map<char, int>::iterator it = map.begin();
            char delChar = it->first;
            int delIndex = it->second;
            while (++it != map.end()) {
                if (it->second < delIndex) {
                    delChar = it->first;       
                    delIndex = it->second;
                }
            }
            map.erase(delChar);
            left = delIndex + 1;
            //找到下标最小的迭代器,让左边界跳转到对应second+1处
        }
        else if (map.size() == 2) {            
        //只有滑动窗口内字符种类等于2,才需要更新子串长度
            maxLen = max(maxLen, right - left);
        }
    }
    return maxLen;
}

两种方法时间效率都是O(n),但是方法二左边界收缩不是单纯地前进一位,而是根据下标最小值,直接跳转到该最小值后一位,所以时间效率更高!!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值