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

网站建设及相关流程图淮南网站制作

网站建设及相关流程图,淮南网站制作,微信营销软件破解版,代码网站模板这是滑动窗口的另一道题目,难度为中等。 让我们来看看题目描述: 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s “cbaebabacd”, p “abc” 输出: …

这是滑动窗口的另一道题目,难度为中等。
让我们来看看题目描述:

给定两个字符串 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” 的异位词。


提示:

  • 1 <= s.length, p.length <= 3 * 1 0 4 10^4 104
  • sp 仅包含小写字母

说人话环节:

给定两个字符串 s 和 p,找到 s 中所有与 p 字符组成相同(顺序不限)的子串,并返回这些子串的起始位置。

题解

class Solution {public List<Integer> findAnagrams(String s, String p) {// 创建一个哈希表,用来存储 p 中每个字符及其需要的出现次数Map<Character, Integer> need = new HashMap<>();// 创建一个哈希表,用来存储当前滑动窗口中各字符的出现次数Map<Character, Integer> window = new HashMap<>();// 遍历 p 中的每个字符,将每个字符的出现次数记录到 need 中for(char c : p.toCharArray()){need.put(c, need.getOrDefault(c, 0) + 1);}// 初始化左右指针,表示滑动窗口的左右边界int left = 0, right = 0;// valid 用来记录窗口中满足 need 条件的字符种数int valid = 0;// 用于存储所有找到的异位词子串的起始索引List<Integer> res = new ArrayList<>();// 开始滑动窗口遍历 s 字符串while(right < s.length()){// 取出当前右边界的字符,并将右指针右移一位char c = s.charAt(right);right++;// 如果当前字符是 p 中需要的字符if(need.containsKey(c)){// 更新窗口中该字符的数量window.put(c, window.getOrDefault(c, 0) + 1);// 如果当前窗口中该字符的数量与 need 中要求的数量相等,valid 加 1if(window.get(c).equals(need.get(c))){valid++;}}// 当窗口大小达到 p 的长度时,开始判断和调整窗口while(right - left >= p.length()){// 如果 valid 等于 need 中键的数量,说明当前窗口中的字符完全满足 p 的要求,是 p 的一个异位词if(valid == need.size()){res.add(left); // 将当前窗口的起始索引加入结果列表}// 准备移除窗口左边界的字符char d = s.charAt(left);left++;// 如果移除的字符是 p 中需要的字符,则更新窗口数据if(need.containsKey(d)){// 如果窗口中该字符的数量正好符合要求,则 valid 需要减 1if(window.get(d).equals(need.get(d))){valid--;}// 窗口中该字符的数量减 1window.put(d, window.get(d)-1);}}}// 返回所有找到的异位词子串的起始索引return res;}
}

我们来回忆一下滑动窗口基本模板:

int left = 0, right = 0;while (right < nums.size()) {// 增大窗口window.addLast(nums[right]);right++;while (window needs shrink) {// 缩小窗口window.removeFirst(nums[left]);left++;}
}

实例

我们以以下实例来大致模拟一下整个过程:

输入:
s = “cbaebabacd”
p = “abc”
输出: [0,6]

整体思路是使用固定大小为 p.length() 的滑动窗口来检测窗口内的字符是否能构成 p 的异位词。当窗口大小达到 p 的长度后,我们需要把窗口最左边的字符移除,为下一次比较腾出位置。

下面是这段代码在窗口缩小时的具体过程:

假设前面已经完成了以下初始化工作:

  • need = {‘a’:1, ‘b’:1, ‘c’:1}(记录 p 中每个字符出现的次数)
  • window:当前窗口中各字符的统计(初始为空)
  • left = 0, right = 当前右指针位置,valid 表示窗口中满足 need 条件的字符种数
  • 当窗口的大小 right - left 等于 p 的长度(即3)时,我们检查 valid 是否等于 need 的大小(3),如果相等就说明窗口中字符完全匹配 p(构成异位词),记录当前 left;随后需要通过调整窗口来继续检测后续位置。

接下来重点看缩小窗口这一段代码(当窗口长度固定为 p 的长度时):

char d = s.charAt(left);
left++;if(need.containsKey(d)){if(window.get(d).equals(need.get(d))){valid--;}window.put(d, window.get(d)-1);
}

我们结合具体的运行过程说明:

1. 初始阶段形成第一个窗口

  • 索引 0 到 2:
    读取字符:
    • s[0] = ‘c’ → 更新 window:{‘c’:1},由于 window[‘c’] 与 need[‘c’] 匹配,valid 从 0 增加到 1。
    • s[1] = ‘b’ → 更新 window:{‘c’:1, ‘b’:1},window[‘b’] 与 need[‘b’] 匹配,valid 增加到 2。
    • s[2] = ‘a’ → 更新 window:{‘c’:1, ‘b’:1, ‘a’:1},window[‘a’] 与 need[‘a’] 匹配,valid 增加到 3。
      此时窗口大小为 3(即 p 的长度),并且 valid 等于 3(need 中不同字符个数),说明从索引 0 开始的子串 “cba” 是一个异位词,因此记录索引 0到结果中。

2. 开始缩小窗口,准备移动窗口

当窗口大小固定为 3 时,需要调整窗口:

  • 移除索引 0 的字符 ‘c’:
    • 执行 char d = s.charAt(left); 取出 ‘c’,然后 left++ 将 left 从 0 变为 1。
    • 检查 if(need.containsKey(d)):‘c’ 在 need 中,所以继续检查。
    • 判断 if(window.get(d).equals(need.get(d))):此时 window[‘c’] 是 1,与 need[‘c’] 也为 1,说明 ‘c’ 正好满足条件,所以 valid 减 1,从 3 变为 2。
    • 然后执行 window.put(d, window.get(d)-1);,将 window[‘c’] 从 1 减为 0。
      此操作完成后,当前窗口变为索引 [1,2](对应字符 “ba”),valid = 2。

这段代码的意义就在于:

  • 将窗口左侧最旧的字符移出窗口
  • 如果移出的字符正好满足 need 的要求(即移除前窗口中该字符的数量刚好符合需要),那么 valid 计数也要减少,因为窗口现在少了一个完全匹配的字符
  • 同时更新 window 中该字符的数量

3. 窗口继续滑动

接下来程序继续将右指针右移,补充窗口字符,再次达到窗口大小为 3后再做判断和移除:

  • 举例说明后续部分(关键节点):
    • 当 right 指针移动并形成新的窗口 “bac” 时(对应索引 6 到 8),窗口中的统计变为 {‘b’:1, ‘a’:1, ‘c’:1},此时 valid 恢复到 3(因为相应字符数量与 need 完全匹配),因此记录索引 6。
    • 紧接着,为了继续滑动窗口,又会执行一次缩小操作:移除当前窗口最左边的字符(如索引 6 的字符 ‘b’),如果移除前 window[‘b’] 恰好等于 need[‘b’](1),那么 valid 就会减少,保证窗口统计更新正确。

这一段代码的作用就是在每次窗口达到固定长度 p.length() 后,通过移除窗口最左边的字符来“滑动”窗口,并同步更新窗口中每个字符的计数以及 valid 指标,从而为后续比较做准备。如果不移除最左边的字符,窗口就会一直增大,就无法保持与 p 长度一致的窗口去判断是否为异位词。

通过不断移动右指针加入新字符,并用这段代码移除旧字符,我们就能遍历整个字符串 s,找出所有符合条件的异位词子串。最终在本例中,我们得到的结果是 [0,6],分别对应 “cba”(索引 0)和 “bac”(索引 6)。

问题与解答

[NOTE] 问题1
window这个hashmap中其实也只会有a、b、c三个key吗?其他的字符只会存在于left到right这个双指针之中对吗?
解答:
是的,window 这个 HashMap 只会存储 p 中出现的字符(在本例中是 ‘a’、‘b’ 和 ‘c’),因为只有当当前字符在 need 中(即在 p 中)时才会将其加入或更新 window。对于 s 中其他不在 p 中的字符,虽然它们依然会被 right 指针经过,但不会加入到 window 中,只在滑动窗口内存在,而不记录在 window 这个映射中。

[NOTE] 问题2
我是否可以这样理解:
window和need这两个hashmap的key其实是一样的,不一样的是value的值,作为要找出的子串hashmap,need中保存每个字符出现的次数,而window的作用只是拿来与need进行对比,在滑动窗口的移动过程中,window中每个key的字符出现次数会改变,所以设置一个valid。
valid++的条件是if (window.get(c).equals(need.get(c))),只有当window和need中的valid == need.size()条件满足时,才会记录左指针left的值存入res。这才是这个算法最重要的判断条件对吗?
解答:
你的理解是正确的。简要总结如下:

  • 相同的 Key 集合
    needwindow 的 key 集合是一样的,都是 p 中出现的字符。

  • value 的含义不同

    • need 保存的是 p 中每个字符需要的出现次数。
    • window 动态记录当前滑动窗口中这些字符的实际出现次数。
  • valid 的作用
    window 中某个字符的出现次数达到 need 中的要求时,就会对 valid 进行累加。只有当 valid 的值等于 need.size() 时,说明当前窗口中的字符种类和数量都满足 p 的要求,此时可以认为这个窗口内的子串是 p 的一个异位词,因此记录下 left 的位置。

这正是该算法的核心判断条件。

完整程序可调试

以下是可在编译器调试的完整代码,需要自取:

import java.util.*;public class test_438 {public static void main(String[] args) {// 输入样例String s = "cbaebabacd";String p = "abc";// 创建 Solution 对象并调用 findAnagrams 方法Solution solution = new Solution();List<Integer> result = solution.findAnagrams(s, p);// 输出结果System.out.println("输出: " + result);}
}class Solution {public List<Integer> findAnagrams(String s, String p) {// 创建 need 哈希表,用于存储 p 中每个字符及其需要的出现次数Map<Character, Integer> need = new HashMap<>();// 创建 window 哈希表,用于存储当前滑动窗口中各字符的出现次数Map<Character, Integer> window = new HashMap<>();// 统计 p 中每个字符出现的次数for (char c : p.toCharArray()) {need.put(c, need.getOrDefault(c, 0) + 1);}int left = 0, right = 0;// valid 用于记录窗口中满足 need 条件的字符种数int valid = 0;// 用于存储所有找到的异位词子串的起始索引List<Integer> res = new ArrayList<>();// 开始滑动窗口遍历 s 字符串while (right < s.length()) {// 当前加入窗口的字符char c = s.charAt(right);right++;// 如果当前字符是 p 中需要的字符,则更新窗口数据if (need.containsKey(c)) {window.put(c, window.getOrDefault(c, 0) + 1);if (window.get(c).equals(need.get(c))) {valid++;}}// 当窗口大小达到 p 的长度时,检查并缩小窗口while (right - left >= p.length()) {// 如果 valid 等于 need 中字符的种数,则说明当前窗口为异位词if (valid == need.size()) {res.add(left);}// 移除窗口最左边的字符,准备缩小窗口char d = s.charAt(left);left++;// 如果移除的字符是 p 中需要的字符,更新窗口数据if (need.containsKey(d)) {if (window.get(d).equals(need.get(d))) {valid--;}window.put(d, window.get(d) - 1);}}}return res;}
}

文章转载自:

http://hcVM7Adc.wqrdx.cn
http://g93S1RHK.wqrdx.cn
http://tnXsJM8P.wqrdx.cn
http://39hYe5dP.wqrdx.cn
http://tlcewjFT.wqrdx.cn
http://FQ5OQlEy.wqrdx.cn
http://SnpdDmWU.wqrdx.cn
http://FGpUs9AI.wqrdx.cn
http://AQCtBmPd.wqrdx.cn
http://Ps3rgU9T.wqrdx.cn
http://sizrGInd.wqrdx.cn
http://wRYeMyRp.wqrdx.cn
http://chTpZJ5H.wqrdx.cn
http://mmnATok4.wqrdx.cn
http://APoHnO3m.wqrdx.cn
http://EZ1DMK2y.wqrdx.cn
http://nzUoNhCX.wqrdx.cn
http://XBTmRtyz.wqrdx.cn
http://NdJHmIKg.wqrdx.cn
http://cF2qObn3.wqrdx.cn
http://GzxvozrO.wqrdx.cn
http://QCvtwNkw.wqrdx.cn
http://4PFrDyem.wqrdx.cn
http://LvHTCyS2.wqrdx.cn
http://mq3Khlcc.wqrdx.cn
http://vt7Go1gF.wqrdx.cn
http://Qvzf5Tzj.wqrdx.cn
http://a4m9lRZv.wqrdx.cn
http://Of2mTFFb.wqrdx.cn
http://rXl8d5N8.wqrdx.cn
http://www.dtcms.com/wzjs/672896.html

相关文章:

  • 多语言网站怎么实现域名查询 站长查询
  • 微信上的网站怎么做的国内做家具外贸的网站
  • 建设门户网站需要注意什么意思建立良好的公共秩序教学设计
  • 东莞数据线厂家东莞网站建设网络营销策划推广公司一一
  • 建设网站需要问的问题手机网站信任从哪里设置
  • 怎么用flashfxp上传网站学习建设网站需要多久
  • 开通网站流程高端seo服务
  • 做网站优化时 链接名称"首页"有必要添加nofollow吗?破解网站后台密码有人做吗
  • 佛山企业网站推广263企业邮箱入口登录方法
  • 网站建设要注意哪些计算机软件开发培训机构
  • 搜狗站长平台主动提交wordpress批量发邮
  • 品牌策划费用哈尔滨优化关键词免费
  • 阿里云服务器可以做商业网站php网站开发工程师招聘要求
  • 北京响应式h5网站开发登錄wordpress界面
  • 中小企业网站制作过程中要注意什么纸巾 技术支持 东莞网站建设
  • 高端网站定制设计公司沭阳建设局网站
  • 淄博市建设局网站营销网站优化推广
  • 重庆网站设计重庆最加科技谷歌浏览器官方app下载
  • 大连百度推广开户网站优化推广 视屏
  • 如何做问卷调查网站论坛交流平台有哪些
  • 鞍山市城乡建设局网站策划书怎么写 范文
  • 网站专门做冻品的WordPress外链网盘
  • 佛山做外贸网站个人网页需要什么内容
  • 南京市雨花区建设局网站检察门户网站 建设意义
  • 徐州丰县建设局网站江苏网站建设公司哪家好
  • 网站怎样做自适应分辨率大小淘宝客可以自己做网站推广吗
  • 注册网站怎么开发WordPress区块的大小
  • 做移动端网站软件下载花蝴蝶在线观看免费版高清
  • 一站式做网站系统区块链app定制开发
  • 江阴市城乡建设网站wordpress文件上传位置修改