IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 718 最长重复子数组(二分查找、字符串哈希) -> 正文阅读

[数据结构与算法]718 最长重复子数组(二分查找、字符串哈希)

1. 问题描述:?

给两个整数数组?A?和?B?,返回两个数组中公共的、长度最长的子数组的长度。

示例:

输入:

A: [1,2,3,2,1]
B: [3,2,1,4,7]

输出:3

解释:

长度最长的公共子数组是 [3, 2, 1] 。

提示:

1 <= len(A), len(B) <= 1000
0 <= A[i],B[i] < 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray

2. 思路分析:

分析题目可以知道这道题目类似于最长公共子序列的问题,这里需要求解的是最长公共子数组问题,最长公共子数组问题也是一个经典的问题,比较好的解决是方法是使用二分来解决,我们可以使用二分计算出当前的mid,在nums1中求解出所以长度为mid的子数组,然后在nums2中判断是否存在长度为mid相等的子数组,根据当前长度为mid的check函数的结果来更新l和r,所以问题就转化为如何快速判断两个连续的子序列是否相等,这里可以使用字符串哈希算法快速判断两个连续的子序列是否相等(判断连续的子序列与字符串是否相等的本质上是一样的,字符串累加的是ascii值,序列累加的是对应的数值),字符串哈希使用O(n)的时间来预处理字符串前缀的哈希值,然后就可以使用O(1)的时间查询出任意一个子串的哈希值,字符串哈希涉及到以下几个公式:

3. 代码如下:

from typing import List


class Solution:
    # 查询数组中[l, r]区间的哈希值, 字符串的哈希数组查询的时候是从下标为1开始的
    def query(self, h: List[int], l: int, r: int, P: int, p: List[int]):
        return h[r] - h[l - 1] * p[r - l + 1]

    def check(self, mid: int, ha: List[int], hb: List[int], n: int, m: int, P: int, p: List[int]):
        hash = dict()
        i = mid
        # 将nums1中所有长度为mid的哈希值加入到哈希表中然后再遍历一下nums2中的所有长度为mid的哈希值如果存在两个哈希值是相等的说明满足要求返回True
        while i <= n:
            hash[self.query(ha, i - mid + 1, i, P, p)] = 1
            i += 1
        i = mid
        # 在nums2中计算所有长度为mid的哈希值并判断是否存在哈希值相等的情况
        while i <= m:
            t = self.query(hb, i - mid + 1, i, P, p)
            if t in hash: return True
            i += 1
        return False

    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        ha, hb = [0], [0]
        # p用来计算p的t次幂
        p = [1]
        # P为经验值, 一般为131,13331这样发生冲突的概率极小可以认为几乎是没有冲突如果发生冲突那么换一个P即可
        P = 131
        n, m = len(nums1), len(nums2)
        # 预处理第一个数组的哈希值
        for i in range(n):
            ha.append(ha[-1] * P + nums1[i])
            p.append(p[-1] * P)
        # 预处理第二个数组的哈希值
        for i in range(m):
            hb.append(hb[-1] * P + nums2[i])
        l, r = 0, n
        res = 0
        while l <= r:
            mid = l + r >> 1
            # 使用res来记录答案, 长度为mid满足条件说明答案应该是在右边
            if self.check(mid, ha, hb, n, m, P, p):
                res = mid
                l = mid + 1
            else:
                r = mid - 1
        return res
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:10:50  更:2021-09-01 12:13:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:22:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码