718. 最长重复子数组

718. 最长重复子数组

原题链接:

718. 最长重复子数组

https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/

完成情况:

题解:

方法一:动态规划

java 复制代码
package 西湖算法题解___中等题;

public class __718最长重复子数组__动态规划 {
	//子数组的话,默认是连续的。
	public int findLength(int[] nums1, int[] nums2) {
		/*
		给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。
		当然了,肯定是要求顺序,而非连续。
		那么必然就需要用到动态数组,采取累积的形式

		 */
		int n = nums1.length,m = nums2.length;
		int dp_findLength [][] = new int[n+1][m+1];
		int res = 0;
		for (int i=n-1;i>=0;i--){
			for (int j=m-1;j>=0;j--){
				dp_findLength[i][j] = (nums1[i] == nums2[j] ? dp_findLength[i+1][j+1] + 1:0);
				res = Math.max(res,dp_findLength[i][j]);
			}
		}
		return res;
	}
}

方法二:滑动窗口


java 复制代码
package 西湖算法题解___中等题;

public class __718最长重复子数组__滑动窗口 {
	public int findLength(int[] nums1, int[] nums2) {
		int n = nums1.length,m = nums2.length;
		int res = 0;
		for (int i=0;i<n;i++){
			int len = Math.min(m,n-i);
			int maxLen = maxLength(nums1,nums2,i,0,len);
			res = Math.max(res,maxLen);
		}
		for (int i=0;i<m;i++){
			int len = Math.min(n,m-i);
			int maxLen = maxLength(nums1,nums2,0,i,len);
			res = Math.max(res,maxLen);
		}
		return res;
	}

	private int maxLength(int[] nums1, int[] nums2, int addA, int addB, int len) {
		int res = 0,k=0;
		for (int i=0;i<len;i++){
			if (nums1[addA+i] == nums2[addB+i]){
				k++;
			}else {
				k=0;
			}
			res = Math.max(res,k);
		}
		return res;
	}
}

方法三:二分查找 + 哈希

java 复制代码
package 西湖算法题解___中等题;

import java.util.HashSet;
import java.util.Set;

public class __718最长重复子数组__二分查找_哈希表 {
	int mod = 1000000009;
	int base = 113;
	public int findLength(int[] nums1, int[] nums2) {
		int left = 1,right = Math.min(nums1.length,nums2.length)+1;
		while (left < right){
			int mid = (left + right) >> 1;
			if (myCheck(nums1,nums2,mid)){
				left = mid +1;
			}else {
				right = mid;
			}
		}
		return left - 1;
	}

	private boolean myCheck(int[] A, int[] B, int len) {
		long hashA = 0;
		for (int i=0;i<len;i++){
			hashA = (hashA * base + A[i]) % mod;
		}
		Set<Long> bucketA = new HashSet<Long>();
		bucketA.add(hashA);
		long mult = qPow(base,len - 1);
		for (int i = len;i < A.length;i++){
			hashA = ((hashA - A[i - len] * mult % mod + mod) % mod * base + A[i]) % mod;
			bucketA.add(hashA);
		}
		long hashB = 0;
		for (int i=0;i<len;i++){
			hashB = (hashB * base +B[i])%mod;
		}
		if (bucketA.contains(hashB)){
			return true;
		}
		for (int i=len;i<B.length;i++){
			hashB = ((hashB - B[i - len] * mult % mod + mod) % mod * base + B[i]) % mod;
			if (bucketA.contains(hashB)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 使用快速幂计算x^n % mod 的值
	 * @param x
	 * @param n
	 * @return
	 */
	private long qPow(long x, long n) {
		long res = 1L;
		while (n != 0){
			if ((n&1) != 0){
				res = res * x % mod;
			}
			x = x*x % mod;
			n >>= 1;
		}
		return res;
	}
}
相关推荐
吃好睡好便好1 小时前
提取矩阵某一行或某一列元素
开发语言·人工智能·线性代数·算法·matlab·矩阵
better_liang4 小时前
每日Java面试场景题知识点之-消息队列MQ核心场景与实战
java·面试·kafka·消息队列·rabbitmq·rocketmq·mq
小江的记录本4 小时前
【JVM虚拟机】垃圾回收GC:四种引用类型:强引用、软引用、弱引用、虚引用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试
圣保罗的大教堂4 小时前
leetcode 2540. 最小公共值 简单
leetcode
小马爱打代码4 小时前
Spring源码 第四篇:Spring 5 源码深度拆解:AOP 全流程核心原理
java·后端·spring
better_liang4 小时前
每日Java面试场景题知识点之-SpringBoot启动流程
java·面试·springboot·源码解析·启动流程
RyFit4 小时前
Java + AI 实战:Spring AI 从入门到企业级落地
java·人工智能·spring
云泽8085 小时前
笔试算法 -位运算篇(二):从唯一字符到消失数字
c++·算法·位运算
ʚ希希ɞ ྀ5 小时前
不同路径|| -- dp
算法
ZhengEnCi6 小时前
01-如何监听接口调用情况?
java·spring boot·后端