Leetcode 3700. Number of ZigZag Arrays II

  • [Leetcode 3700. Number of ZigZag Arrays II](#Leetcode 3700. Number of ZigZag Arrays II)
    • [1. 解题思路](#1. 解题思路)
    • [2. 代码实现](#2. 代码实现)

1. 解题思路

这一题事实上就是上一题3699. Number of ZigZag Arrays I的进阶版本,主要的变化就是增加了 n n n的复杂度, n n n最大可以取到 1 0 9 10^9 109,因此暴力的迭代显然就不现实了,但其核心的迭代公式依然还是上一题中分析的那样:
{ u n + 1 i = ∑ j = i + 1 r d n j d n + 1 i = ∑ j = l i − 1 u n j \left\{ \begin{aligned} u_{n+1}^i &= \sum\limits_{j=i+1}^{r} d_{n}^{j} \\ d_{n+1}^i &= \sum\limits_{j=l}^{i-1} u_{n}^{j} \end{aligned} \right. ⎩ ⎨ ⎧un+1idn+1i=j=i+1∑rdnj=j=l∑i−1unj

这里,注意到,如果我们令 v ⃗ = c o n c a t ( u ⃗ , d ⃗ ) \vec{v} = \mathop{concat}(\vec{u}, \vec{d}) v =concat(u ,d ),那么事实上上述迭代过程可以写作是一个矩阵乘法:
v ⃗ n + 1 = M ⋅ v ⃗ n \vec{v}{n+1} = M \cdot \vec{v}{n} v n+1=M⋅v n

因此,不难推导:
v ⃗ n = M n − 1 ⋅ v ⃗ 1 \vec{v}{n} = M^{n-1} \cdot \vec{v}{1} v n=Mn−1⋅v 1

此时,问题也就变成了如何快速地求矩阵 M M M的 n − 1 n-1 n−1了,这个就变成了一个常规的二分处理的算法了。

当然,既然这里涉及到了矩阵乘法,因此,我们自然而然就可以使用numpy来加速一下运算了,这里就不过多展开了。

2. 代码实现

给出python代码实现如下:

python 复制代码
import numpy as np

MOD = 10**9 + 7
    
class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        d = r-l+1
        vec = [1 for _ in range(d-1)] + [0] + [0] + [1 for _ in range(d-1)] 
        vec = np.array(vec, dtype=object)

        M = [[0 for _ in range(2*d)] for _ in range(2*d)]
        for i in range(d):
            for j in range(i+1, d):
                M[i][d+j] = 1
            for j in range(i):
                M[i+d][j] = 1
        M = np.array(M, dtype=object)

        def pow_mul(M, vec, n):
            res = vec
            while n:
                if n % 2 == 1:
                    res = (M @ res) % MOD
                M = (M @ M) % MOD
                n = n // 2
            return res                

        res = pow_mul(M, vec, n-1)
        return sum(res) % MOD

提交代码评测得到:耗时4045ms,占用内存31.78MB。

相关推荐
Miraitowa_cheems33 分钟前
LeetCode算法日记 - Day 84: 乘积为正数的最长子数组长度
数据结构·算法·leetcode·贪心算法·线性回归·深度优先·动态规划
鸽鸽程序猿1 天前
【算法】【动态规划】斐波那契数模型
算法·动态规划·1024程序员节
Brookty1 天前
【算法】前缀和(二)使用
java·学习·算法·前缀和·动态规划·1024程序员节
敲上瘾1 天前
背包dp——动态规划
c++·算法·动态规划
自在极意功。2 天前
动态规划核心原理与高级实战:从入门到精通(Java全解)
java·算法·动态规划·最优子结构·重叠子问题
nju_spy2 天前
力扣每日一题(三)划分题 + 思路题
数学·算法·leetcode·动态规划·笔试·记忆化搜索·状态压缩
闻缺陷则喜何志丹2 天前
【单调队列 多重背包】P1776 宝物筛选|普及+
c++·算法·动态规划·洛谷·多重背包·单调队列
熬了夜的程序员2 天前
【LeetCode】80. 删除有序数组中的重复项 II
java·数据结构·算法·leetcode·职场和发展·排序算法·动态规划
2401_841495643 天前
【强化学习】动态规划算法
人工智能·python·算法·动态规划·强化学习·策略迭代·价值迭代
天选之女wow4 天前
【代码随想录算法训练营——Day43(Day42周日休息)】动态规划——300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组
算法·leetcode·动态规划