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

航空网站建设长沙百度网站快速排名

航空网站建设,长沙百度网站快速排名,深圳公司注册登记中心,网站建设的具体方法子串 1. 和为 k 的子数组题目描述解题思路主要思路步骤 时间复杂度与空间复杂度代码实现 2. 滑动窗口最大值题目描述解题思路双端队列的原理:优化步骤: Java实现 3. 最小覆盖子串题目描述解题思路滑动窗口的基本思路:具体步骤:算法…

子串

    • 1. 和为 k 的子数组
      • 题目描述
      • 解题思路
        • 主要思路
        • 步骤
      • 时间复杂度与空间复杂度
      • 代码实现
    • 2. 滑动窗口最大值
      • 题目描述
      • 解题思路
        • 双端队列的原理:
        • 优化步骤:
      • Java实现
    • 3. 最小覆盖子串
      • 题目描述
      • 解题思路
        • 滑动窗口的基本思路:
        • 具体步骤:
        • 算法的关键点:
      • Java实现

1. 和为 k 的子数组

题目描述

给定一个整数数组 nums 和一个整数 k,你需要在数组中找到连续子数组的个数,使得这些子数组的和等于 k

解题思路

我们可以通过 前缀和 的方法来高效解决这个问题,结合 哈希表 来记录每个前缀和出现的次数,从而迅速计算出满足条件的子数组。

主要思路
  1. 前缀和的定义

    • 对于数组 numsprefix[i] 表示从 nums[0]nums[i-1] 的和。也就是说,prefix[i] = nums[0] + nums[1] + ... + nums[i-1]
    • 子数组的和 nums[i..j] 可以表示为:prefix[j+1] - prefix[i]。因此,如果我们希望找到 nums[i..j] 的和为 k,那么只需要满足 prefix[j+1] - prefix[i] = k
  2. 如何利用哈希表

    • 在遍历数组时,我们可以计算当前的前缀和 pre
    • 然后,我们通过 map.containsKey(pre - k) 来判断是否存在一个前缀和为 pre - k 的位置,这样就找到了一个子数组和为 k
    • 我们还需要维护一个哈希表 map,其中 map.get(pre) 表示当前前缀和 pre 出现的次数。这样做是为了确保我们能够计算出所有符合条件的子数组。
  3. 核心算法

    • 初始化哈希表 map,将 0 的计数初始化为 1,因为如果前缀和刚好为 k,就意味着从数组起始位置开始的子数组和为 k
    • 遍历数组并更新前缀和,并利用哈希表记录前缀和的出现次数。
步骤
  1. 初始化

    • pre = 0 表示当前的前缀和。
    • cnt = 0 表示符合条件的子数组数量。
    • map 存储前缀和及其出现次数,初始时将 map.put(0, 1),即前缀和为 0 出现 1 次。
  2. 遍历数组

    • 对于每个元素,更新前缀和 pre
    • 检查哈希表中是否存在 pre - k,如果存在,说明从某个位置到当前位置的子数组和为 k,则将其出现次数加到 cnt 中。
    • 更新哈希表,将当前前缀和 pre 出现的次数加 1。
  3. 返回结果

    • 遍历完所有元素后,cnt 中存储的就是符合条件的子数组数量。

时间复杂度与空间复杂度

  • 时间复杂度O(n),其中 n 是数组 nums 的长度。我们只需要遍历一次数组,同时进行常数时间的哈希表操作。
  • 空间复杂度O(n),我们需要使用哈希表存储前缀和及其出现次数,最坏情况下哈希表的大小为 n

代码实现

class Solution {public int subarraySum(int[] nums, int k) {int len = nums.length;int pre = 0, cnt = 0;HashMap<Integer, Integer> map = new HashMap<>();map.put(0, 1); // 初始化,前缀和为0的有1个,这样做不会忽略掉“从数组起始位置开始的和为 k 的子数组”。for (int i = 0; i < len; i++) {pre += nums[i]; // 计算当前前缀和if (map.containsKey(pre - k)) {  // 说明从某个位置到当前位置存在连续子数组和为 kcnt = cnt + map.get(pre - k); // 增加符合条件的子数组的数量}// 更新哈希表,记录当前前缀和出现的次数map.put(pre, map.getOrDefault(pre, 0) + 1); }return cnt; // 返回符合条件的子数组数量}
}

2. 滑动窗口最大值

题目描述

给定一个整数数组 nums 和一个滑动窗口的大小 k,请你在数组中找出每个滑动窗口的最大值,并返回一个数组。

解题思路

这道题目是一个典型的滑动窗口问题。直接暴力计算每个窗口中的最大值的时间复杂度是 O(n*k),这种做法在数据量较大的情况下效率较低。因此,我们可以使用 双端队列(Deque) 来优化这一过程。

双端队列的原理:
  • 双端队列是一种支持从两端高效插入和删除的队列结构。我们可以利用它来存储数组元素的下标,并保持队列中的元素按照值的大小顺序排列。这样可以确保队列的第一个元素永远是当前窗口中的最大值。
优化步骤:

及时去掉无用数据,保证双端队列有序(当前数组>=队尾,弹出队尾;弹出队首不在窗口内的元素)

  1. 使用一个双端队列 q 来存储窗口中的元素的下标。
  2. 保证队列中的元素下标对应的值是递减的,队列的首部始终是窗口的最大值。
  3. 每次移动窗口时:
    • 入队操作:将新元素的下标加入队列,并从队列的尾部移除所有小于当前元素的值,以保证队列保持递减顺序。
    • 出队操作:如果队列头部的元素已经不再在当前窗口范围内(即超出窗口的左边界),则将其从队列中移除。
    • 记录结果:当窗口大小达到 k 时,记录当前窗口的最大值,即队列头部的元素。

Java实现

class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;Deque<Integer> q = new ArrayDeque<>(); // 存的是nums的下标int[] ans = new int[n - k + 1];for (int i = 0; i < n; i++) {// 1. 入队:保持队列中的元素递减while (!q.isEmpty() && nums[i] >= nums[q.getLast()]) {q.removeLast();}q.addLast(i); // 队列存的是下标// 2. 出队:如果队列的第一个元素不在窗口内,移除它if (i - q.getFirst() >= k) {q.removeFirst();}// 3. 存结果:当窗口大小达到k时,记录最大值if (i >= k - 1) {ans[i - k + 1] = nums[q.getFirst()];}}return ans;}
}

3. 最小覆盖子串

题目描述

给定字符串 s 和字符串 t,找到 s 中包含 t 中所有字符的最小子串。如果 s 中没有包含 t 中所有字符的子串,则返回空字符串。

解题思路

这是一个经典的滑动窗口问题。我们需要在字符串 s 中找到一个最小的子串,该子串包含了 t 中所有字符。最初我们可以考虑暴力解法,但暴力解法会超时,因此我们需要使用 滑动窗口 技巧来优化算法。

滑动窗口的基本思路:
  1. 滑动窗口的定义:我们维护一个窗口,窗口的大小是可变的,在窗口内包含了 t 中的所有字符。
  2. 扩展窗口:从字符串 s 的开始位置开始扩展窗口,逐步包含 t 中的字符。
  3. 收缩窗口:当窗口已经包含了 t 中的所有字符时,尝试缩小窗口的大小,以找到更小的符合条件的子串。
  4. 窗口合法性:当窗口内包含所有 t 中的字符时,窗口是合法的。
具体步骤:
  1. 使用两个指针 leftright 表示滑动窗口的左右边界,初始化时都指向字符串 s 的开头。
  2. 使用两个哈希表 cntTcntS 来记录 t 中字符的出现频率和当前窗口中字符的出现频率。
  3. 当窗口包含 t 中的所有字符时,尝试缩小窗口的左边界。
  4. 在每次扩展和收缩窗口时,更新当前的最小子串。
算法的关键点:
  • 记录 t 中所有字符的频率。
  • 使用两个指针维护滑动窗口。
  • 记录窗口内字符的频率并与 t 中的字符频率进行比较。

Java实现

class Solution {public String minWindow(String s, String t) {int ansLeft = -1;int m = s.length();int ansRight = m;// 记录t的字符出现的次数Map<Character, Integer> cntT = new HashMap<>();for (char c : t.toCharArray()) {cntT.put(c, cntT.getOrDefault(c, 0) + 1);}// 记录s的字符出现的次数Map<Character, Integer> cntS = new HashMap<>();int left = 0;int formed = 0;  // 记录s和t覆盖的字符的个数int required = cntT.size();  // 记录t中的不同字符的个数for (int right = 0; right < m; right++) {char sr = s.charAt(right);cntS.put(sr, cntS.getOrDefault(sr, 0) + 1);// 如果s中的字符完全匹配t中的字符if (cntT.containsKey(sr) && cntS.get(sr).intValue() == cntT.get(sr).intValue()) {formed++;}// 当s子串能覆盖t的时候收缩窗口while (formed == required) {if (right - left < ansRight - ansLeft) {ansLeft = left;ansRight = right;}// 收缩窗口char leftChar = s.charAt(left);cntS.put(leftChar, cntS.get(leftChar) - 1);if (cntT.containsKey(leftChar) && cntS.get(leftChar).intValue() < cntT.get(leftChar).intValue()) {formed--;}left++;}}return ansLeft < 0 ? "" : s.substring(ansLeft, ansRight + 1); // 左闭右开}
}
http://www.shuangfujiaoyu.com/news/39117.html

相关文章:

  • 网站首页置顶是怎么做谷歌手机版下载安装
  • 贵州门户网站建设如何在百度上发布自己的文章
  • 金山区做网站吗青岛网站
  • dedecms模板站源码如何在百度上做广告
  • 免费论坛网站大全关键的近义词
  • 单位做网站备案用身份证有啥用外贸业务推广
  • 平原做网站北京百度推广代理
  • 变化型网页网站有哪些搜索引擎最新排名
  • 网站单页网络营销推广技巧
  • 代购网站怎么做的网站怎么找
  • web期末网站设计论文友情链接交换条件
  • wordpress这个博客seo关键词快速排名
  • 如何做优惠券运营网站淘宝店铺买卖交易平台
  • 怎么给网站添加站点统计郑州网站排名优化外包
  • 纯文本网站免费无代码开发平台
  • 建个个人网站一年多少钱营销型网站制作企业
  • 做电脑网站用什么软件好用吗网站推广软件免费版大全
  • 麻城网站建设鞍山seo优化
  • 图片瀑布流网站产品推广文案怎么写
  • wordpress 怎么上传视频东莞网站优化公司哪家好
  • 网站建设 天津seo技术自学
  • 义乌国贸学校网站建设网站制作厂家有哪些
  • 云龙微网站开发企业官网首页设计
  • 台州建设网站公司网络推广怎么收费
  • 怎么自己建设一个网站seo企业优化方案
  • 网站被做301跳转了怎么办电商网站建设 网站定制开发
  • 网站开发报告下载优化大师安装桌面
  • ps做网站 字体多大怎样推广app
  • 音响网站模板免费下载seo是什么职位的简称
  • 网站建设总结报告站长工具综合查询官网