滑动窗口(找连续的子串专用)------双指针

适用的范围:

注意点:

例题:

Leetcode003无重复字符的最长字串:

y总解法:

题解:

代码:

Leetcode053:

描述:

 地址:


适用的范围:

输入是数组或者字符串,求解的结果是题目要求的子数组或者子字符串。(子数组或者子字符串必须是连续的。!!!!!)

注意点:

例题:

Leetcode003无重复字符的最长字串:

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

y总解法:

思路见:https://www.acwing.com/problem/content/801/

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
    //存储每一个字符在[j,i]区间里出现的次数
    unordered_map<char,int> heap;
    int res=0;
    int l=s.length();
    for(int i=0,j=0;i<l;i++ ){
    //加入一个新的字符s[i],出现次数+1
     heap[s[i]]++;
     //加入的数已经出现过一次了,从j开始一直删(heap[s[j]--])
     //直到把重复的那个字符(即这次我们加入的字符=>s[i])给删了(即heap[s[i]==0]),j就停
     while(j<=i&&heap[s[i]]>1){
         heap[s[j]]--;
         j++;
     }
     res=max(res,i-j+1);
}
return res;
    }
};

题解:

 

 

代码:

java版(较麻烦)

public int lengthOfLongestSubstring(String s) {
        //总体思路: 用哈希表保存当前滑动窗口窗口的元素(保存每个元素索引)。
// 如果窗口右边界指向的元素已经在哈希表中,则将窗口的起点重置为哈希表中重复元素的下一个位置
        // 每一次迭代都通过max函数比较选出滑动窗口的最大长度。
        Map<Character,Integer> map=new HashMap<>();
//创建一个Map集合,key用来存储字母,value用来存储字母的下标
        int left=0;int right=0;//分别代表窗口的左右边界
        int max=0;//最大不重复字串的长度。
        for(right=0;right<s.length();right++){
            //先判断右边界的字母是否重复,决定左边界要不要动
            char t=s.charAt(right);//把右边界的字母提取出来
            if(map.containsKey(t))
            {
              left=Math.max(map.get(t)+1,left );
       //问题一:
       //为什么要将窗口的起点重置为哈希表中重复元素的下一个索引,而不是起点++呢?
// 我们知道假如起点的位置<=重复元素的位置,那么此时[left,right]区间里面是一定还有重复元素的。
//只是重复++,其实只是在浪费时间,还不如直接跳到对应位置。
      //问题二:
      //为什么不直接取left=map.get(t)+1,而采用left=Math.max(map.get(t)+1,left );
     //这段代码是用来规避哈希表查询到在滑动窗口左边的重复字符的。
    // 例如,在"tmmzuxt"这个字符串中,遍历到最后一步时,最后一个字符't'和第一个字符't'是相等的。
    // 如果没有max函数锁定住滑动窗口的左边界,left就会变为第一个t的位置+1,
//最后输出的最长无重复子串会变成"mmzuxt",这是我们不希望看到的。
            }
            max=Math.max(right-left+1,max);
            map.put(t,right);
        }
        return max;

Leetcode053:

描述:

 地址:

具体可以看我写的文章,这里就不再写一遍了。

https://blog.csdn.net/qq_52934831/article/details/119334656

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值