当前位置: 首页 > article >正文

力扣热题 100:滑动窗口专题两道题详细解析(JAVA)

文章目录

    • 前言
    • 一、无重复字符的最长子串
      • 1. 题目描述
      • 2. 示例
      • 3. 解题思路
      • 4. 代码实现(Java)
      • 5. 复杂度分析
    • 二、找到字符串中所有字母异位词
      • 1. 题目描述
      • 2. 示例
      • 3. 解题思路
      • 4. 代码实现(Java)
      • 5. 复杂度分析

前言

昨晚健身玩臂力器,干到自己下巴了,给眼镜干飞出去20米,下巴也破了个小口,就是因为我没有带好保护绳,长记性了。
在这里插入图片描述

一、无重复字符的最长子串

1. 题目描述

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

2. 示例

示例 1:

输入:s = "abcabcbb"

输出:3

解释:因为最长的无重复字符子串是 "abc",所以长度为 3。

示例 2:

输入:s = "bbbbb"

输出:1

解释:因为最长的无重复字符子串是 "b",所以长度为 1。

示例 3:

输入:s = "pwwkew"

输出:3

解释:因为最长的无重复字符子串是 "wke",所以长度为 3。

3. 解题思路

这道题主要考察滑动窗口的应用。我们可以使用滑动窗口来维护一个无重复字符的子串,通过移动窗口的左右边界来更新子串的长度。具体步骤如下:

  1. 初始化两个指针 leftright,分别表示滑动窗口的左右边界。
  2. 使用一个哈希表 map 来存储当前窗口内的字符及其索引。
  3. 遍历字符串,对于每个字符 s[right]
    • 如果该字符已经在哈希表中存在,且其索引大于等于 left,则移动 left 指针到该字符的下一个位置。
    • 更新哈希表中该字符的索引为 right
    • 计算当前窗口的长度 right - left + 1,并更新最大长度。
  4. 重复步骤 3,直到 right 遍历完整个字符串。

4. 代码实现(Java)

import java.util.HashMap;

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character, Integer> map = new HashMap<>();
        int left = 0, right = 0, maxLength = 0;
        while (right < s.length()) {
            char c = s.charAt(right);
            if (map.containsKey(c) && map.get(c) >= left) {
                left = map.get(c) + 1;
            }
            map.put(c, right);
            maxLength = Math.max(maxLength, right - left + 1);
            right++;
        }
        return maxLength;
    }
}

5. 复杂度分析

  • 时间复杂度 :O(n),其中 n 是字符串的长度。我们只需要遍历字符串一次,每次移动指针的时间复杂度都是 O(1)。
  • 空间复杂度 :O(min(n, m)),其中 m 是字符集的大小。在最坏情况下,哈希表中存储了所有字符。

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

1. 题目描述

给定两个字符串 sp,找到 s 中所有 p 的字母异位词的起始索引。字母异位词指的是包含相同字符且每个字符出现次数相同的字符串。

2. 示例

示例 1:

输入:s = "cbaebabacd", p = "abc"

输出:[0, 6]

解释:起始索引为 0 的子串是 "cba",起始索引为 6 的子串是 "bac"

示例 2:

输入:s = "abab", p = "ab"

输出:[0, 1, 2]

解释:起始索引为 0 的子串是 "ab",起始索引为 1 的子串是 "ba",起始索引为 2 的子串是 "ab"

3. 解题思路

这道题主要考察滑动窗口的应用。我们可以使用滑动窗口来维护一个固定长度的子串,通过移动窗口的左右边界来检查子串是否是字母异位词。具体步骤如下:

  1. 初始化两个指针 leftright,分别表示滑动窗口的左右边界。
  2. 使用两个数组 windowtarget 来存储当前窗口内的字符计数和目标字符串的字符计数。
  3. 遍历字符串 s,对于每个字符 s[right]
    • 更新当前窗口内的字符计数 window
    • 如果窗口的大小等于目标字符串的长度,检查 windowtarget 是否相等。
    • 如果相等,记录当前窗口的起始索引。
    • 移动 left 指针,更新当前窗口内的字符计数 window
  4. 重复步骤 3,直到 right 遍历完整个字符串。

4. 代码实现(Java)

public class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> result = new ArrayList<>();
        int[] window = new int[26];
        int[] target = new int[26];
        for (char c : p.toCharArray()) {
            target[c - 'a']++;
        }
        int left = 0, right = 0;
        while (right < s.length()) {
            window[s.charAt(right) - 'a']++;
            if (right - left + 1 == p.length()) {
                if (Arrays.equals(window, target)) {
                    result.add(left);
                }
                window[s.charAt(left) - 'a']--;
                left++;
            }
            right++;
        }
        return result;
    }
}

5. 复杂度分析

  • 时间复杂度 :O(n),其中 n 是字符串 s 的长度。我们只需要遍历字符串一次,每次移动指针的时间复杂度都是 O(1)。
  • 空间复杂度 :O(1),我们只使用了固定大小的数组来存储字符计数。

以上就是力扣热题 100 中与滑动窗口相关的两道题的详细解析,希望对大家有所帮助。在实际刷题过程中,建议大家多动手实践,理解解题思路的本质,这样才能更好地应对各种算法问题。


http://www.kler.cn/a/562719.html

相关文章:

  • macpro m1 安装deepseek
  • Python【数据处理】高级编程
  • 流程管理和质量体系管理怎样有效的整合
  • SSD 固态硬盘存储密度的分区
  • 什么是 Java 中的线程安全?
  • react中,在组件内返回style标签方法
  • mysql有索引但是查询没有使用索引是什么问题
  • mac修改docker的daemon.json 镜像文件
  • DeepSeek:面向效率与垂直领域的下一代大语言模型技术解析
  • Deepseek底层技术解析:构建下一代对话式AI的核心架构
  • 【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题
  • C语言实现通讯录项目
  • 基于Zigbee的三车协作智能小车项目改进方案
  • python学习四
  • 计算机视觉:经典数据格式(VOC、YOLO、COCO)解析与转换(附代码)
  • idea创建第一个springboot程序
  • 数据开发面试:DQL,
  • 深入解析 Linux /etc/skel 目录的作用与使用方法
  • C# 打印Word文档 – 4种打印方法
  • PDF转HTML 超级好用 免费在线转换PDF 完美转换格式