【算法】 滑动窗口—最长无重复子串

        “无重复字符的最长子串”,难度为Medium,看下题目:

        输入一个字符串 s,请计算 s 中不包含重复字符的最长子串长度。

        比如,输入 s = "aabab",算法返回2,因为无重复的最长子串是 "ab" 或者 "ba",长度为2。

        这道题终于有了点新意,不是一套框架就出答案,不过反而更简单了,稍微改一改框架就行了:

package SlidingWindow;

import java.util.HashMap;
import java.util.Map;

// leetcode 016 最长无重复子串
public class LNRS {

    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> window = new HashMap<>(); // 记录窗口中的相应字符的出现次数
        int left = 0, right = 0;
        int res = 0; // 记录结果
        while (right < s.length()) {
            // c 是将要移入窗口的字符
            char c = s.charAt(right);
            // 右移窗口
            right++;
            // 进行窗口内数据的一系列更新
            window.put(c, window.getOrDefault(c, 0) + 1);

            /*** debug 输出的位置***/
            System.out.println("window:(" + left + ", " + right + ")");
            /*********************/

            // 判断左侧窗口是否要收缩
            while (window.put(c, window.getOrDefault(c, 0)) > 1) { // window need shrink —窗口需要收缩
                // d 是将要移出窗口的字符
                char d = s.charAt(left);
                // 左移窗口
                left++;
                // 进行窗口内数据的一系列更新
                window.put(d, window.getOrDefault(d, 0) - 1);
            }
            // 在这里更新答案
            res = Math.max(res, right - left);
        }
        return res;
    }

    public static void main(String[] args) {
        LNRS lnrs = new LNRS();
        int res = lnrs.lengthOfLongestSubstring("aabab");
        System.out.println(res);
    }

}

        连 need 和 valid 都不需要,而且更新窗口内数据也只需要简单更新计数器 window 即可。

        当 window[c] 值大于1时,说明窗口中存在重复字符,不符合条件,就该移动 left 缩小窗口了。

        唯一需要注意的是,在哪里更新结果 res 呢?我们要的是最长无重复子串,哪一个阶段可以保证窗口中的字符是没有重复的呢?这里和之前不一样,要在收缩窗口完成后更新 res,因为窗口收缩的 while 条件是存在重复元素,换句话说收缩完成后一定保证窗口中没有重复。

滑动窗口算法可以用来找到字符串中的最大重复子串。该算法使用一个滑动窗口来扫描字符串,并通过调整窗口的大小和位置来找到最大重复子串。 具体步骤如下: 1. 首先,定义一个窗口的左边界和右边界,初始值都为0。 2. 然后,定义一个字符计数数组cnt,用于记录窗口内每个字符的出现次数。 3. 接下来,定义一个变量maxCount,用于记录窗口内出现次数最多的字符的出现次数。 4. 开始遍历字符串,将右边界向右移动一位,并更新字符计数数组和出现次数最多的字符的出现次数。 5. 如果窗口的宽度大于可能的最大长度(即窗口的宽度大于滑动窗口的长度),则需要缩小窗口的左边界和更新字符计数数组。 6. 在每次遍历过程中,更新最大重复子串的长度(即窗口的宽度)。 7. 遍历结束后,返回最大重复子串的长度。 这样,滑动窗口算法就可以找到字符串中的最大重复子串。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [2021.05.11滑动窗口最长重复子串](https://blog.csdn.net/Zack_zc_zc/article/details/123683394)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [最长重复子串(Rabin-Karp算法)](https://blog.csdn.net/qq_41687938/article/details/118312273)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值