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

leetcode 567. 字符串的排列

LeetCode 链接

字符串的排列


题目描述

给定两个字符串 s1s2,判断 s2 中是否存在一个连续子串,其字符组成与 s1 完全相同(顺序无关)。例如,若 s1 = "ab",则合法的子串可以是 "ab""ba" 或其他任意排列组合。

​示例 1​​:

输入:s1 = "ab"s2 = "eidbaooo"

输出:true

解释:s2 中存在子串 "ba",其字符组成与 s1 相同。

​示例 2​​:

输入:s1 = "ab"s2 = "eidboaoo"

输出:false

解释:s2 中所有长度为 2 的子串均不满足字符组成要求。


核心思路

本题的关键在于高效判断 s2 中是否存在与 s1 字符组成相同的子串。由于直接暴力枚举所有可能的子串会导致时间复杂度过高(如 s2 长度为 1e4 时,子串数量可达百万级),因此需要借助滑动窗口和字符计数的技巧来优化。


解法一:暴力枚举(直观但低效)

​思路​​:

  1. 统计 s1 中各字符的出现次数。
  2. 遍历 s2 的所有可能子串(长度等于 s1),逐一比对字符计数是否一致。

​代码实现​​:

class Solution {public boolean checkInclusion(String s1, String s2) {if (s1.length() > s2.length()) return false;// 统计s1的字符频率Map<Character, Integer> target = new HashMap<>();for (char c : s1.toCharArray()) {target.put(c, target.getOrDefault(c, 0) + 1);}// 枚举s2的所有长度为s1.length()的子串for (int i = 0; i <= s2.length() - s1.length(); i++) {Map<Character, Integer> window = new HashMap<>();for (int j = i; j < i + s1.length(); j++) {char c = s2.charAt(j);window.put(c, window.getOrDefault(c, 0) + 1);}// 判断当前窗口是否与目标完全匹配if (target.equals(window)) return true;}return false;}
}

​特点​​:

✅ 代码逻辑简单直观

❌ 时间复杂度为 O(m*n)mn 分别为 s1s2 的长度),无法通过大数据量测试


解法二:滑动窗口 + 动态计数(最优解)

​核心思想​​:

通过维护一个固定大小的窗口(长度等于 s1),逐步向右滑动窗口,实时更新窗口内的字符计数,并与 s1 的计数进行比对。当窗口计数完全匹配时,立即返回结果。

​关键优化点​​:

  1. ​滑动窗口​​:避免重复计算,每次只需处理新增和移出的字符。
  2. ​数组代替哈希表​​:利用 ASCII 码的特性,用长度为 26 的数组存储字符计数,提升查询效率。

​代码实现​​:

class Solution {public boolean checkInclusion(String s1, String s2) {if (s1.length() > s2.length()) return false;int[] target = new int[26];  // s1的字符计数int[] window = new int[26]; // 当前窗口的字符计数// 初始化窗口和目标计数for (int i = 0; i < s1.length(); i++) {target[s1.charAt(i) - 'a']++;window[s2.charAt(i) - 'a']++;}// 初步比对if (Arrays.equals(target, window)) return true;// 滑动窗口for (int i = s1.length(); i < s2.length(); i++) {// 添加新字符char newChar = s2.charAt(i);window[newChar - 'a']++;// 移出旧字符char oldChar = s2.charAt(i - s1.length());window[oldChar - 'a']--;// 判断是否匹配if (Arrays.equals(target, window)) return true;}return false;}
}

​特点​​:

✅ 时间复杂度优化至 O(n)(仅需遍历一次 s2

✅ 空间复杂度优化至 O(1)(固定大小数组)

❌ 需要处理字符计数的动态增减逻辑


代码对比与选择建议

方法时间复杂度空间复杂度适用场景
暴力枚举O(m*n)O(m)数据量极小(如面试题)
滑动窗口O(n)O(1)实际工程场景

​总结​​:滑动窗口方案通过巧妙的动态计数和窗口滑动策略,将时间复杂度从 O(m*n) 降低到线性级别,是本题的最优解。建议优先掌握该方法,并理解其核心思想——通过维护固定窗口减少重复计算。

http://www.dtcms.com/a/450417.html

相关文章:

  • 抚顺地区网站建设儒枫网网站建设
  • 网站seo优化技能网站 建设网站
  • WordPress多页切换菜单南山网站优化
  • 手写MyBatis第94弹:调试追踪MyBatis SQL执行流程的终极指南
  • 凡科网电脑版怎么做网站上海广告网站建设
  • wordpress 语言包安徽建站优化
  • 网站要怎样建设合川网站优化
  • 企业购物网站建设浙江重大工程交易网
  • SSM--day1--Spring(一)--IOCBeanDI
  • C++ 修饰符类型
  • 淄博网站建设常见问题网址地址查询域名
  • PSP 支持中文文件名的 GBA 模拟器
  • 《内部阵列电极提高基于电阻层析成像的软触觉传感器的空间分辨率》ICRA2019论文解读
  • 电子商务中网站开发成都网站制作设计公司
  • wordpress全站采集wordpress 强制更新
  • 建设银行 网站招聘网站开发兼职
  • 文库网站建设开发搭建一个网站需要什么
  • 2024ICPC成都I题好分割Good Partitions
  • 字节跳动2025面试专业问题集锦
  • 前端设计与布局常用术语(前端术语中英对照速查表)
  • Typescript return type
  • 做网站关键词必须要中文网址pc做网站服务器
  • MySQL包安装 -- RHEL系列(离线RPM包安装MySQL)
  • 计算机组成原理:多核处理机实例
  • wordpress 内置tag外贸网站优化哪家好
  • 机器学习算法部分demo
  • 网站的电子画册怎么做网络营销软文范例500字
  • 做司考题的网站广东网站备案时间
  • 东莞网站优化关键词推广网站开发合肥
  • 微博网站建设免费做网站广告