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

本文详细解析了如何使用滑动窗口优化的方法解决LeetCode上的最长不重复子串问题,通过两种不同的算法思路,包括暴力求解和滑动窗口优化,分析了其时间复杂度,并给出了C++的实现代码。这种方法能够有效地减少时间复杂度,提高算法效率。
摘要由CSDN通过智能技术生成

练习地址:力扣

思路解析:

方法一:考虑暴力的做法,对于每一个字符串利用双指针扫描,每扫描一次利用map存储一次当前字符出现的次数,如果发现有一个字符在之前出现过,则 i 指针向后移动一位,继续令 j=i+1重新扫描,时间复杂度O(N^2) .

方法二:利用滑动窗口优化.思路是这样的,假设有一个字符串bcadeafg,我们将 j 和 i 指针一开始都置于0位置,接着i指针不动, i 指针像暴力做法一样向下扫描,每扫描一个都一样将当前扫描到的字符出现的次数存放在hash表中,也就是h[s[ i ] ]++的操作,当扫描完bcade的时候一切正常这时候 i 指针指向了a,发现a在 j ~ i 的子串之间出现了两次,所以出现了重复这时候我们将 j 指针移动到a的位置,并将沿路的字符出现的次数减去1,对于新位置再次重复以上操作,其中需要记录(i-j+1)也就是每次发现出现字符重复时候的子串长度,进行更新.

      证明:现在来解释一下为什么 j 指针可以直接移动到第一个重复的字符的位置,假设不是 j 移动到a停止而是移动到c停止,那么仍然存在重复字符,并且由于 i 和 j之间包含了重复字符,所以即使 j 只向前移动一个位置,i 如果暴力回来重新循环的话,i再次到达第二个a的时候最长的子串长度肯定不会超过j位于b时候的 ,因为少了一个字符的长度,所以j位于第一个重复字符的前面的比较毫无意义,只需要记录一下位于最开始位置的那个最长不重复子串就行了.所以干脆直接把 j 移动到第一个重复a的位置重新开始比较.

c++实现:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
      int res=0; //存储结果
      unordered_map<char,int>h; //定义哈希表,记录某一个字符在j~i之间出现的次数
      for(int i=0,j=0;i<s.size();i++)
      {
          h[s[i]]++;  //首先将当前扫描到的字符个数加一
          while(h[s[i]]>1) h[s[j++]]--; //如果发现当前字符重复了,则j往前移动将沿途的字符出现次数减一,直到遇到重复字符当中的第一个
          res=max(res,i-j+1); //对比每次i指针遇到重复字符时候的长度,选取最大的长度记录结果
      }
      return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值