Fancy DSA Fancy DSA
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)

Jonsam NG

想的更多,也要想的更远
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)
  • 开始上手
  • Plan 计划
  • Roadmap 路线
  • 算法简介
  • Sort 排序

  • Search 搜索

  • Recursive 递归

  • Graph 图

  • Tree 树

  • Math 数学

  • Hash 哈希

  • String 字符串

  • BitManipulation 位操纵

  • Backtracking 回溯

  • DynamicProgramming 动态规划

    • ClimbingStairs [爬楼梯]
    • CoinChange [钱币兑换]
    • EditDistance [编辑距离]
    • FibonacciNumber [斐波那契数]
    • FindMonthCalendar [月历]
    • KadaneAlgo [最大连续子数组和之Kadane算法]
    • LevenshteinDistance [莱文斯坦距离]
    • LongestCommonSubsequence [最长公共子序列]
    • LongestIncreasingSubsequence [最长递增子序列]
    • LongestPalindromicSubsequence [最长回文子序列]
    • LongestValidParentheses [最长合法括号]
    • MaxNonAdjacentSum [最大非连接子集和]
    • MaxProductOfThree [最大三数积]
    • MinimumCostPath [最小代价路径]
    • NumberOfSubsetEqualToGivenSum [等和子集]
    • RodCutting [棒材切割问题]
    • Shuf [随机样本]
    • SieveOfEratosthenes [埃拉托斯特尼筛法]
    • SlidingWindow [滑窗]
      • 介绍
      • 案例
      • 参考
    • SudokuSolver [数独]
    • TrappingRainWater [接住雨水]
    • TribonacciNumber [翠波那契数]
    • ZeroOneKnapsack [零一背包]
  • Cache 缓存

  • Array 数组

  • Ciphers 密码学

  • Conversions 转换

  • ProjectEuler 欧拉计划

  • 其他

  • 算法
  • DynamicProgramming 动态规划
jonsam
2022-10-18
目录

SlidingWindow [滑窗]

# 介绍

滑窗技术是一种计算技术,其目的是减少嵌套循环的使用,用单个循环代替,从而降低时间复杂性。

什么是滑窗?考虑一条连接在一起的长链。假设你想用你的手在整条链条上涂油,而不从上面倒油。一种方法是:将一些油涂抹在链条的一个部分,然后再次将一些油涂在下一个尚未涂油的部分,以此类推,直到整条链条都上了油。另一种方法是用一块布,蘸上油,然后用这块布抓住链条的一端。然后不用再重复蘸油,只需用手将布滑到下一节,再下一节,以此类推,直到另一端。

第二种方法被称为滑动窗口技术,从一端滑动到另一端的部分,被称为滑动窗口(Sliding Window)。

使用滑动窗口技术的先决条件:

滑动窗口技术的使用可以在一个非常特殊的情况下进行,在整个嵌套循环中,计算窗口的大小是固定的。只有这样才能降低时间的复杂性。

如何使用滑动窗口技术?

滑动窗口技术的一般使用方法可以演示如下:

  • 找到所需的窗口大小。
  • 从数据结构的开始计算第一个窗口的结果。
  • 然后用一个循环来滑动窗口,并继续逐窗计算结果。

# 案例

# 最长不重复子串

获取不含重复字符的最长子串的长度。

/**
 * @function LongestSubstringWithoutRepeatingCharacters
 * @description Get the length of the longest substring without repeating characters
 * @param {String} s - The input string
 */
function LongestSubstringWithoutRepeatingCharacters (s) {
  let maxLength = 0
  let start = 0
  let end = 0
  const map = {}
  while (end < s.length) {
    if (map[s[end]] === undefined) {
      map[s[end]] = 1
      maxLength = Math.max(maxLength, end - start + 1)
      end++
    } else {
      while (s[start] !== s[end]) {
        delete map[s[start]]
        start++
      }
      delete map[s[start]]
      start++
    }
  }
  return maxLength
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 是否包含排列

给定两个字符串 s1 和 s2,如果 s2 包含 s1 的排列,则返回真,否则返回假。

/**
 * @function PermutationinString
 * @description Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise.
 * @param {String} s1 - The input string
 * @param {String} s2 - The input string
 * @return {boolean} - Returns true if s2 contains a permutation of s1, or false otherwise.
 */

function PermutationinString (s1, s2) {
  if (s1.length > s2.length) return false
  let start = 0
  let end = s1.length - 1
  const s1Set = SetHash()
  const s2Set = SetHash()
  for (let i = 0; i < s1.length; i++) {
    s1Set[s1[i]]++
    s2Set[s2[i]]++
  }
  if (equals(s1Set, s2Set)) return true
  while (end < s2.length - 1) {
    if (equals(s1Set, s2Set)) return true
    end++
    const c1 = s2[start]
    const c2 = s2[end]
    if (s2Set[c1] > 0) s2Set[c1]--
    s2Set[c2]++
    start++
    if (equals(s1Set, s2Set)) return true
  }
  return false
}
function equals (a, b) {
  return JSON.stringify(a) === JSON.stringify(b)
}

function SetHash () {
  const set = new Set()
  const alphabets = 'abcdefghijklmnopqrstuvwxyz'
  for (let i = 0; i < alphabets.length; i++) {
    set[alphabets[i]] = 0
  }
  return set
}

// Example 1:
// Input: s1 = "ab", s2 = "eidbaooo"
// Output: true
// Explanation: s2 contains one permutation of s1 ("ba").

// Example 2:
// Input: s1 = "ab", s2 = "eidboaoo"
// Output: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 最大和子数组

给定一个正整数数组和一个正数 k,找到长度为 k 的连续子数组的最大和。

def getMaxSum(arr, k): 
    maxSum = 0 
    windowSum = 0 
    start = 0 

    for i in range(len(arr)): 
        windowSum += arr[i] 

        if ((i - start + 1) == k): 
            maxSum = max(maxSum, windowSum) 
            windowSum -= arr[start] 
            start += 1 

    return maxSum
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 参考

  • Window Sliding Technique - GeeksforGeeks (opens new window)
  • 一文详解滑动窗口技术 - 知乎 (opens new window)
编辑 (opens new window)
上次更新: 2022/10/27, 20:28:55
SieveOfEratosthenes [埃拉托斯特尼筛法]
SudokuSolver [数独]

← SieveOfEratosthenes [埃拉托斯特尼筛法] SudokuSolver [数独]→

最近更新
01
0-20题解
10-31
02
本章导读
10-31
03
算法与转换:Part1
10-28
更多文章>
Theme by Vdoing | Copyright © 2022-2022 Fancy DSA | Made by Jonsam by ❤
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式