leetcode 滑动窗口系列刷题记录

滑动窗口:是双指针算法的一种,可以大致理解为一个指针走的快,一个指针走的慢

算法题应用场景:

关键字:1.满足(计算结果,出现次数,包含)条件

               2.最长/最短

               3.子数组/子串(连续的子集)

常用模板(最大)

初始化l,r,result,bestresult
while(右指针没有到结尾){
   窗口扩大,加入right对应元素,更新当前result
   while(result不满足要求){
   窗口缩小,移除l对应元素,l右移
   }
   更新最优结果bestsult
   right++;
}
return bestresult;

无重复字符的最长子串

中等

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

分析:因为题目要求不重复,所以首先想到哈希表来保存,利用右指针遍历,左指针不满足不重复条件就

缩小窗口,左指针右移

时间复杂度O(n) 空间复杂度O(m)(m为set中不重复的元素)

import java.util.HashSet;

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int len=s.length();
        if(len==0)return 0;
        int l=0,r=0;
        int curccnt=0;
        int bestcnt=0;
        HashSet<Character> set=new HashSet<>();
       while (r<len){
               while (set.contains(s.charAt(r))){
                   set.remove(s.charAt(l));
               l++;
           }
               set.add(s.charAt(r));
               bestcnt=Math.max(bestcnt,set.size());
               r++;
               
       }
       return bestcnt;
    }
}

找到字符串中所有字母异位词

中等

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

 将p中的元素视为有限资源个数的“消耗品”,并统计字母个数,当“消耗品”不足,唯一可以做的就是移动左窗口释放一些出来。右指针向右遍历时,如果该元素个数大于零,将字母元素个数减一,否则左指针右移,并将元素个数加一。这样做的原因是保证左指针到右指针右侧的元素不出现字符串p以外的字母,并确保了不会超出字符串p中每个字母的最大个数。所以当长度为字符p的长度时,他们就互为字符异位词。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> list=new ArrayList<>();
        int len=s.length();
        int len_p=p.length();
        if(len==0||len_p==0)return null;
        int r=0,l=0;
        char []cnt=new char[26];
        for(char ch:p.toCharArray()){
            cnt[ch]++;
        }
        while (r<len){
         if(cnt[s.charAt(r)]>0){
             cnt[s.charAt(r++)]--;
             if(r-l==len_p)list.add(l);
         }
         else {
             cnt[s.charAt(l++)]++;
         }
        }
        return list;
    }
}

结论:如果想要保证两个字符串满足两个条件

1,他们的字母个数相同

2,他们的都包含相同的字母

     可以优先采用个数统计的方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值