美文网首页
前缀和与哈希表综合应用

前缀和与哈希表综合应用

作者: madao756 | 来源:发表于2020-06-19 17:14 被阅读0次

前缀和和哈希表的综合应用非常重要,今天我来总结一下

0X00 题目特征

最重要的特征就是「连续子数组」这一特征,在以前我可能会使用双端队列去做,但是发现有些题目不可证明。

碰到这个「连续子数组」这一特征你大概要想到三种思路:

  • dp
  • 前缀和与哈希表
  • 双端队列

0X01 算法思想

首先我们知道前缀和有这么一个思想:sums[i] - sums[j] 就可以得到 [j+1, i] (包含左右端点)的和的信息。

现在我们有这么一个基础问题:560. 和为K的子数组

题目大致意思是:我们要找到所有和为 K 的所有子数组。

假设数组为 A,应用前缀和知识,我们可以求出以任意节点结尾的前缀和。也就是说,我们只需要遍历任意节点之前的前缀和,就能求出以任意节点为结尾的子数组的和。这样做的时间复杂度就是妥妥的 O(n^2)

但是,如果我们用一个 map 记录所有的前缀,只需要计算我们需要的前缀,再去 map 里面找。这样的时间复杂度就是 O(n)

基于这个思想我们来做四道题:

0X02 相关题目

560. 和为K的子数组

from collections import Counter

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        n = len(nums)
        nums = [0] + nums
        c, sums = Counter(), [0] * (1+n)
        c[0] = 1
        for i in range(1, n+1): sums[i] = sums[i-1] + nums[i]
        res = 0
        for i in range(1, n+1):
            v = sums[i]
            t = v - k
            if t in c: res += c[t]
            c[v] += 1

        return res 

974. 和可被 K 整除的子数组

from collections import Counter
class Solution:
    def subarraysDivByK(self, a: List[int], k: int) -> int:
        n = len(a)
        sums, a = [0] * (n+1), [0] + a
        c = Counter()
        c[0] = 1
        res = 0
        for i in range(1, n+1): sums[i] = sums[i-1] + a[i]

        for i in range(1, n+1):
            s = sums[i]
            t = s % k
            if t in c: res += c[t]
            c[t] += 1
        
        return res

        

1248. 统计「优美子数组」

from collections import Counter
class Solution:
    def numberOfSubarrays(self, nums: List[int], k: int) -> int:
        n = len(nums)
        sums = [0] * (1+n)
        for i in range(1, 1+n): 
            sums[i] = sums[i-1]
            if nums[i-1] & 1:
                sums[i] = sums[i-1] + 1
        c = Counter()
        c[0] = 1
        res = 0
        for i in range(1, 1+n):
            v = sums[i]
            t = v - k
            if t in c: res += c[t]
            c[v] += 1
        
        return res

1371. 每个元音包含偶数次的最长子字符串

class Solution:
    def findTheLongestSubstring(self, s: str) -> int:
        n = len(s)
        sums, m, res = [0] * (1+n), {}, 0
        m[0] = 0
        for i in range(1, n+1):
            sums[i] = sums[i-1]
            c  = s[i-1]
            if c == 'a':
                sums[i] ^= 1
            elif c == 'e':
                sums[i] ^= 1 << 1
            elif c == 'i':
                sums[i] ^= 1 << 2
            elif c == 'o':
                sums[i] ^= 1 << 3
            elif c == 'u':
                sums[i] ^= 1 << 4
            t = sums[i]
            if t in m:
                res = max(res, i - m[t])
            else:
                m[t] = i
        
        return res

每个题的思想基本一致,除了最后一题有些小技巧外,并没有什么特别的地方

0X02 注意事项

  • 一定要注意 map 初始化的时候,0 值的确定

相关文章

  • 前缀和与哈希表综合应用

    前缀和和哈希表的综合应用非常重要,今天我来总结一下 0X00 题目特征 最重要的特征就是「连续子数组」这一特征,在...

  • Leetcode【523、525、560、974】

    引言: 以下四道 Leetcode 题目属于典型数组问题处理方法。它们采取类似的方法:利用哈希表保存数组前缀(前缀...

  • 右手Redis(Redis的高级数据结构)

    一、哈希表的功能和应用 哈希表(Hash Table)是一种数据结构,它实现了“键-值”(Key-Value) 的...

  • 数据结构与算法

    一、线性表及应用 二、线性表的链式存储结构 三、栈与栈的应用 四、哈希表与树 五、二叉树遍历的应用之分治法 六、加...

  • 算法笔记之前缀树

    前缀树 前缀树(trie)又被称为字典树,是一种树形结构,是哈希树的变种。典型应用是用于统计和排序大量的字符串(但...

  • MySQL索引简述--哈希索引

    哈希算法 哈希算法时间复杂度为O(1),且不只存在于索引中,每个数据库应用中都存在该数据结构。 哈希表 哈希表也为...

  • Java 集合

    向量与哈希表

  • golang 字典map

     当在哈希表中查找某个与键值对应的元素值时,我们需要先把键值作为参数传给这个哈希表。哈希表会先用哈希函数(hash...

  • Leetcode-692 前k个高频单词

    这道题的解法分为两种: 哈希表 + 堆 前缀树 解法分类: 根据堆种类可分为:大顶堆(比较神奇)和小顶堆 根据是否...

  • 哈希函数和哈希表

    哈希函数 定义 输入域是无穷的,输出域S是有限的。 输入参数一旦确定,返回值一定是相同的,不存在随机性;多个不同的...

网友评论

      本文标题:前缀和与哈希表综合应用

      本文链接:https://www.haomeiwen.com/subject/mwhbxktx.html