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

Leetcode 3463. Check If Digits Are Equal in String After Operations II

  • Leetcode 3463. Check If Digits Are Equal in String After Operations II
    • 1. 解题思路
    • 2. 代码实现
  • 题目链接:3463. Check If Digits Are Equal in String After Operations II

1. 解题思路

这道题是题目Leetcode 3461的进阶版本,其实就是提高了对于算法效率的要求。

这道题我们实际就是要求s[:-1]s[1:]这两个字符串操作为最终一个字符之后的值是否相同。而将一个数字字符串按照给定操作变成最终一个字符,其原始字符串当中每一位参与的次数事实上就是一个杨辉三角,这个是很明显的。

因此,这里的问题事实上就变成了如何快速求出杨辉三角的第 n n n行的全部元素。考虑到我们最终是要考虑其个位数,因此事实上我们要求的是杨辉三角的第 n n n行上每一个元素的个位数,即其对 10 10 10的模。

有数学知识我们可以得到,杨辉三角的第 n n n行的第 k k k个元素事实上就是组合数 C n k C_n^k Cnk,但是当我们要求其对 10 10 10的模的时候,这个问题就变得有点复杂了。不过,考虑到 10 = 2 × 5 10 = 2 \times 5 10=2×5,然后由中国剩余定理,我们只需要分别求出 C n k C_n^k Cnk 2 2 2 5 5 5的余数,我们就必然可以一一对应的找出其对于 10 10 10的余数,这个简单关系如下:

nmod 2mod 5
000
111
202
313
404
510
601
712
803
914

但是,实际做题的时候我被卡在了这一步,后面没有搞定,但是问了一下deepseek之后,它给出了一个非常数学的解法,即使用Lucas定理进行快速求解。

我们首先给出Lucas定理的说明:

对于一个组合数 C n k C_n^k Cnk,要求其对于某一个素数 p p p的模,我们只需要将 n , k n, k n,k分别展开为 p p p进制数,即:
n = ∑ i = 0 m n i ⋅ p i k = ∑ i = 0 m k i ⋅ p i \begin{aligned} n &= \sum\limits_{i=0}^{m}n_i \cdot p^i \\ k &= \sum\limits_{i=0}^{m}k_i \cdot p^i \\ \end{aligned} nk=i=0mnipi=i=0mkipi
则我们有:
C n k ≡ Π i = 0 m C n i k i ( m o d   p ) C_n^k \equiv \mathop{\Pi}\limits_{i=0}^m C_{n_i}^{k_i} (mod\ p) Cnki=0ΠmCniki(mod p)

由此,我们就可以在任意 O ( l o g p n ) O(log_pn) O(logpn)的算法复杂度范围内求出任意组合数 C n k C_n^k Cnk关于 2 2 2 5 5 5的模了,进而,由上述模的对应关系,我们即可得到我们的最终答案。

2. 代码实现

给出python代码实现如下:

def comb_mod2(n, k):
    """ 计算 C(n, k) mod 2 """
    if k < 0 or k > n:
        return 0
    # 检查k的二进制位是否均为n对应位的子集
    return 0 if (k & ~n) else 1

# 预计算C(ni, ki) mod5的值(ni和ki为0-4)
mod5_comb_table = [
    [1, 0, 0, 0, 0],  # n=0
    [1, 1, 0, 0, 0],  # n=1
    [1, 2, 1, 0, 0],  # n=2
    [1, 3, 3, 1, 0],  # n=3
    [1, 4, 1, 4, 1],  # n=4(C(4,2)=6 mod5=1,C(4,3)=4 mod5=4)
]

def comb_mod5(n, k):
    """ 计算 C(n, k) mod 5 """
    result = 1
    while n > 0 or k > 0:
        ni = n % 5
        ki = k % 5
        if ki > ni:
            return 0
        # 查预计算表获取C(ni, ki) mod5
        result = (result * mod5_comb_table[ni][ki]) % 5
        n = n // 5
        k = k // 5
    return result

# 中国剩余定理映射表(a mod2,b mod5)→ 结果 mod10
crt_map = {
    (0, 0): 0,
    (0, 1): 6,
    (0, 2): 2,
    (0, 3): 8,
    (0, 4): 4,
    (1, 0): 5,
    (1, 1): 1,
    (1, 2): 7,
    (1, 3): 3,
    (1, 4): 9,
}

def get_element_mod10(i, j):
    """ 计算杨辉三角第i行第j个元素的个位数(索引从0开始) """
    if j < 0 or j > i:
        return 0
    a = comb_mod2(i, j)   # 计算模2
    b = comb_mod5(i, j)   # 计算模5
    return crt_map[(a, b)]

class Solution:
    def hasSameDigits(self, s: str) -> bool:
        n = len(s)
        weights = [get_element_mod10(n-2, i) for i in range(n-1)]
        
        def fn(s):
            ans = 0
            n = len(s)
            for i, ch in enumerate(s):
                digit = int(ch)
                ans = (ans + weights[i] * digit) % 10
            return ans
        
        return fn(s[:-1]) == fn(s[1:])

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/33753.html

相关文章:

  • 2025版-Github账号注册详细过程
  • 【C语言】第八期——指针
  • UE_C++ —— Logging in Unreal
  • 初识XML
  • LeetCode 热题 100 206. 反转链表
  • ASP.NET Core Clean Architecture
  • 如何选择适合自己电脑的本地部署模型,模型的大小与b之间的关系,模型参数,量化Q
  • 嵌入式之内存管理
  • 【Git】多人协作
  • 【c++】【线程池】线程池模式
  • Python常见面试题的详解16
  • DeepSeek掘金——基于DeepSeek-R1构建文档问答机器人
  • C 语言文件操作
  • Seata1.5.2学习(二)——使用分布式事务锁@GlobalLock
  • 微信小程序 - 页面跳转(wx.navigateTo、wx.redirectTo、wx.switchTab、wx.reLaunch)
  • Python--函数入门
  • Docker 网络详解
  • 正则表达式--元字符-特殊符号(5)
  • vue+element-plus简洁完美实现淘宝网站模板
  • 【STM32】内存管理
  • UE_C++ —— Delegates
  • 网络安全营运周报
  • 【Linux系统编程】网络编程
  • 机器学习数学通关指南——拉格朗日乘子法
  • 汽水分离器 酿酒不锈钢碳钢蒸汽发生器锅炉空气旋风式油水分离器
  • Python----数据分析(Numpy一:numpy库简介,与list列表的区别,数组的创建,随机数组的创建)
  • 一、初始爬虫
  • 基于数据可视化学习的卡路里消耗预测分析
  • VisActor/VTable - 快速搭建表格
  • 【HeadFirst系列之HeadFirst设计模式】第10天之迭代器与组合模式:遍历与管理的艺术