【LeetCode 手撕算法】(滑动窗口) 3-无重复字符的最长子串、438-找到字符串中所有字母异位词

3-无重复字符的最长子

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

示例 1

输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。

示例 2:

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

示例 3:

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

请注意,你的答案必须是 子串 的长度,"pwke"是一个*子序列,*不是子串。

思路: 求子串的最长值,说明是变化的,选用滑动窗口。两指针都在最左端,右指针持续 探路,窗口从0开始加入元素 并持续判断是否重复。若出现重复 则删除最左端,直到窗口内不重复为止。右指针走完就结束,这个过程中记录窗口的长度。

java 复制代码
//----滑动窗口模版-----
//外层循环扩展右边界,内层循环扩展左边界
for (int l = 0, r = 0 ; r < n ; r++) {
	//当前考虑的元素
	while (l <= r && check()) {//区间[left,right]不符合题意
        //扩展左边界
    }
    //区间[left,right]符合题意,统计相关信息
}
java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[]ch= s.toCharArray();       //把string变成char
        Set<Character> win=new HashSet<>();  //窗口需要hash去重
        int max=0;
        for(int l=0,r=0;r<ch.length;r++){
            while(win.contains(ch[r])){   //一直判断窗口win内是否含有右指针
                win.remove(ch[l]);       //有就删除左指针,直到干净
                l++;
            }
            win.add(ch[r]);     //若窗口win无,则右指针加入窗口
            max=Math.max(max,r-l+1); //记录窗口最大时的值
        }
        return max;
    }
}

细节注意:

1、contains( ) 拼写别少了s

2、char ch= s.toCharArray(); 必须把string长串变成char数组,方便用双指针

3、Set<Character> win=new HashSet<>(); 滑动窗口必须用集合去重,别忘记<>, HashSet为固定实现类,Character为格式

4、Math 大写

5、左指针要一直去重,if只能判断一次,while可以一直判断。 举例 abcac,abcac,abca****c ,++a++++bcac,abcac,abcac++ 其中左指针连续减了两次


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

给定两个字符串 sp,找到 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" 的异位词。

思路:

异位词即每个字母出现次数相同,因此选用26位int数组。由于异位词的二者长度相同,由此可以确定窗口大小,即p的长度。s的窗口从i=0开始移动,到s长-p长+1为止,每移动一次进行哈希统计,并于hashP比较,是否相同。

java 复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        char[] winS=s.toCharArray();
        char[] winP=p.toCharArray();
        int [] hashP=new int[26];
        ArrayList<Integer> list= new ArrayList<>();
        for(int i=0;i<winP.length;i++){
            hashP[winP[i]-'a']++;
        }
        for(int i=0;i<winS.length-winP.length+1;i++){
            int [] hashS=new int[26];
            for(int j=i;j<i+winP.length;j++){
                hashS[winS[j]-'a']++;
            }
            if(Arrays.equals(hashS,hashP)){list.add(i);}
            
        }
        return list;
    }
}

注意事项:

1、比较地址内容用 a.equals(b) 比较数组内容用Arrays.equals(a,b)

2、每次查完hashS必须进行清空,不能直接hashS=0,因为左右两种数据类型不一致,可以重新初始化,int hashS=new int26;

3、动态添加数组用ArrayList<Integer> list= new ArrayList<>();

4、String类型不能用 .length算长度,必须转成char

相关推荐
小刘在重生~41 分钟前
Java 集合|Collection、List、ArrayList、LinkedList、泛型、Collections 工具类
java·数据结构·list
EDPJ1 小时前
(2026|IPI|我的论文投稿中,PSP 超轻量采样算法,轻量化架构探索/早融合+头压缩)LUMIN:面向工业异常检测的轻量级通用制造检测网络
算法·计算机视觉·架构·异常检测·采样算法
我不会起名字3221 小时前
一天一道算法题(29):单调栈
java·数据结构·python·算法·leetcode·golang·单调栈
苦瓜小生1 小时前
【前端】【力扣与手撕】十天带你刷完前端算法与手撕,全是最简单好记的最优解法!day4
前端·数据结构·算法·leetcode·面试
不会就选b2 小时前
算法日常・每日刷题--<贪心>5
算法
圣保罗的大教堂2 小时前
leetcode 2029. 石子游戏 IX 中等
leetcode
刘广睿2 小时前
素材去重为什么难?文件指纹、感知哈希与相似度判定的设计笔记
算法·哈希算法·产品设计·素材管理
少司府2 小时前
C++进阶:智能指针
开发语言·数据结构·c++·b树·算法·c·智能指针
鹿角片ljp3 小时前
LeetCode 22:括号生成|回溯dfs、剪枝与 char[] 覆盖代替撤销
算法·深度优先
sylviiiiiia3 小时前
leetcode hot100
python·算法·leetcode