首页 > 其他分享 >前缀和经典问题整理

前缀和经典问题整理

时间:2023-05-23 23:36:43浏览次数:63  
标签:pre 前缀 nums int self range 经典 整理 matrix

1、一般形式  --  区域和检索 - 数组不可变

class NumArray:

    def __init__(self, nums: List[int]):
        self.pre = [0]
        for num in nums:
            self.pre.append(self.pre[-1] + num)
        ####或者#####
        self.pre = list(accumulate(nums, initial=0))

    def sumRange(self, left: int, right: int) -> int:
        return self.pre[right + 1] - self.pre[left]

2、经典问题 --  连续数组

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。

class Solution:
    def findMaxLength(self, nums: List[int]) -> int:
        pre, m = 0, {0: -1}
        maxl = 0
        for i, num in enumerate(nums):
            pre += 1 if num == 1 else -1
            if m.get(pre, None) != None:
                maxl = max(i - m[pre], maxl)
            else:
                m[pre] = i
        return maxl

3、二维数组前缀和和差分

(1)二维数组前缀和 -- 二维区域和检索 - 矩阵不可变

 代码:

class NumMatrix:

    def __init__(self, matrix: List[List[int]]):
        self.sum_matrix = [[0] * len(matrix[0]) for _ in matrix]
        for i in range(len(matrix)):
            row_sum = 0
            for j in range(len(matrix[i])):
                row_sum += matrix[i][j]
                self.sum_matrix[i][j] = self.sum_matrix[i - 1][j] + row_sum

    def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
        res = self.sum_matrix[row2][col2]
        if col1 > 0: res -= self.sum_matrix[row2][col1 - 1]
        if row1 > 0: res -= self.sum_matrix[row1 - 1][col2]
        if col1 > 0 and row1 > 0: res += self.sum_matrix[row1 - 1][col1 - 1]
        return res

(2)二维数组差分 -- 子矩阵元素加 1

class Solution:
    def rangeAddQueries(self, n: int, queries: List[List[int]]) -> List[List[int]]:
        d = [[0] * (n + 1) for _ in range(n + 1)]
        for r1, c1, r2, c2 in queries:
            d[r1][c1] += 1
            d[r2 + 1][c2 + 1] += 1
            d[r1][c2 + 1] -= 1
            d[r2 + 1][c1] -= 1
        
        ans = [[0] * (n + 1) for _ in range(n + 1)]
        for i, row in enumerate(d[:n]):
            for j, x in enumerate(row[:n]):
                ans[i + 1][j + 1] = ans[i + 1][j] + ans[i][j + 1] - ans[i][j] + x
        del ans[0]
        for row in ans:
            del row[0]
        return ans

数组差分可以看成函数微分,数组前缀和可以看成函数积分,所以差分数组的前缀和就是原数组

4、进阶问题

(1)统计回文子序列数目

class Solution:
    def countPalindromes(self, s: str) -> int:
        suf = [0] * 10
        suf2 = [0] * 100
        for d in map(int, reversed(s)):
            for j, c in enumerate(suf):
                suf2[d * 10 + j] += c
            suf[d] += 1

        ans = 0
        pre = [0] * 10
        pre2 = [0] * 100
        for d in map(int, s):
            suf[d] -= 1
            for j, c in enumerate(suf):
                suf2[d * 10 + j] -= c  # 撤销
            ans += sum(c1 * c2 for c1, c2 in zip(pre2, suf2))  # 枚举所有字符组合
            for j, c in enumerate(pre):
                pre2[d * 10 + j] += c
            pre[d] += 1
        return ans % (10 ** 9 + 7)

(2)统计上升四元组

class Solution:
    def countQuadruplets(self, nums: List[int]) -> int:
        n = len(nums)
        more = [[0] * n for _ in range(n + 1)]
        less = [[0] * n for _ in range(n + 1)]
        for j in reversed(range(n)):
            for k in reversed(range(j + 1, n)):
                if nums[j] < nums[k]:
                    more[k][j] = more[k + 1][j] + 1
                else:
                    more[k][j] = more[k + 1][j]

        for k in range(n):
            for j in range(k):
                if nums[k] > nums[j]:
                    less[j][k] = less[j - 1][k] + 1
                else:
                    less[j][k] = less[j - 1][k]
        
        res = 0
        for k in range(n):
            for j in range(k):
                if nums[k] < nums[j]:
                    res += less[j][k] * more[k][j]
        
        return res

 

标签:pre,前缀,nums,int,self,range,经典,整理,matrix
From: https://www.cnblogs.com/usaddew/p/17426758.html

相关文章

  • MySQL数据基础知识整理—4
        今天我们了解下MySQL数据库中的索引和最基础的事务是什么吧。注意:本次的索引会作为主要讲解部分,事务会分两部分讲解;希望大家在看本文章前先看完我之前的MySQL数据基础知识整理。索引    索引:是一种用于快速查找数据库中特定数据的数据结构。它类似于书籍的目录,可......
  • 字符编码(笔记整理)
    一、知识储备三大核心硬件所有软件都是运行硬件之上的,与运行软件相关的三大核心硬件为cpu、内存、硬盘,我们需要明确三点软件运行前,软件的代码及其相关数据都是存放于硬盘中的任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行软件运行过程中产生的数......
  • ts整理
    定义普通类型变量leta:string='字符串'定义数组letarr:string[]=['1','2','3']letarr:Array=[1,2,3]定义混合数组letarr:(string|number)[]=['1','2',3]类型别名使用type定义typearrmixin=(string|number)[]letarr:arrmi......
  • 十大经典排序算法总结
    排序算法可以分为:内部排序:数据记录在内存中进行排序。外部排序:因排序的数据很大,内存不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序、计数排序、桶排序。其中比较类......
  • 期末加分整理
    快期末了,建民老师说写下博客,把自己的加分总结一下,为此进行整理一下自己这学期的加分。一共加分是1分。第一次+0.5是在打卡app上:地址:2023年3月6日软工日报-阿飞藏泪-博客园(cnblogs.com)第二次+0.5是地铁演示: ......
  • 8百多经典古诗学习鉴赏ACCESS\EXCEL数据库
    虽然古诗类的数据搞到过很多,但是有鉴赏、译文等鉴赏类字段的还是很少,而今天搞到一个古诗学习类数据库,虽然记录数不多,但大都有翻译、鉴赏、译文等字段内容,是小学生、中学生、高中生学习的好东西。朝代统计:金朝(2)、两汉(22)、明代(25)、南北朝(24)、清代(27)、宋代(348)、唐代(373)、魏晋(19)、五......
  • MySQL数据基础知识整理—3
    聚合函数我们先来看下定义:    在数据库中,聚合函数是指能够对一组数据进行计算并返回一个单一值的函数,这个单一值通常是对这组数据的总体统计结果。    简单来说,就是数据库提供给用户的一种常用函数,其中包括和,平均值,最大值,最小值等。下面我也会给出几个比较常用的聚合......
  • 经典的快速排序算法
    经典的快速排序算法其中将一个数组按照枢纽元的大小将其分成左右两个部分的算法成为快速算法这个写个避免了判断相等的情况当遇到元素与枢纽元相等时停止目的是为了产生两个相对平衡的左右数组voidtestQuickSort(){intarr[]={2,4,3,9,6,5,7,0,2,1};//int......
  • 激光建图、定位学习资源整理
    自用,侵删知乎:https://zhuanlan.zhihu.com/p/113616755github:https://github.com/Little-Potato-1990/localization_in_auto_drivinggitee:https://gitee.com/suyunzzz/learn_localization_in_auto_drivinghttps://github.com/suyunzzz/sensor-fusion-for-localization-and-mappi......
  • 【整理】CSS知识点
    1、=========================================css注释/*这是个注释*/2、=========================================选择器id选择器#para1{}class选择器.center{}p.centerclass为center的所有p元素3、===========......