leetcode1537. 最大得分(动态规划-java)

2023-09-18 16:38:09

题目描述

难度 - 困难
leetcode1537. 最大得分

你有两个 有序 且数组内元素互不相同的数组 nums1 和 nums2 。
一条 合法路径 定义如下:

选择数组 nums1 或者 nums2 开始遍历(从下标 0 处开始)。
从左到右遍历当前数组。
如果你遇到了 nums1 和 nums2 中都存在的值,那么你可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。

得分定义为合法路径中不同数字的和。
请你返回所有可能合法路径中的最大得分。
由于答案可能很大,请你将它对 10^9 + 7 取余后返回。

示例1:
在这里插入图片描述输入:nums1 = [2,4,5,8,10], nums2 = [4,6,8,9]
输出:30
解释:合法路径包括:
[2,4,5,8,10], [2,4,5,8,9], [2,4,6,8,9], [2,4,6,8,10],(从 nums1 开始遍历)
[4,6,8,9], [4,5,8,10], [4,5,8,9], [4,6,8,10] (从 nums2 开始遍历)
最大得分为上图中的绿色路径 [2,4,6,8,10] 。

示例 2:
输入:nums1 = [1,3,5,7,9], nums2 = [3,5,100]
输出:109
解释:最大得分由路径 [1,3,5,100] 得到。

示例 3:
输入:nums1 = [1,2,3,4,5], nums2 = [6,7,8,9,10]
输出:40
解释:nums1 和 nums2 之间无相同数字。
最大得分由路径 [6,7,8,9,10] 得到。

示例 4:
输入:nums1 = [1,4,5,8,9,11,19], nums2 = [2,3,4,11,12]
输出:61

提示:
1 <= nums1.length <= 10^5
1 <= nums2.length <= 10^5
1 <= nums1[i], nums2[i] <= 10^7
nums1 和 nums2 都是严格递增的数组。
在这里插入图片描述

动态规划

这道题,我们最终是要合并出一条逻辑上的最大直线,因此遇到相同值时,我们就面临选择,因此我们可以用动态规划去解决:
我们用f(i) 和 g(j) 来分别表示遍历到数组 nums1[i]和 nums2[j]时的最大得分。如果遍历到的元素没有合并,那么它只会从相同数组的前一个元素转移而来:
f(i) = f(i - 1) + nums[i];
g(j) = g(j - 1) + nums2[j];

如果遍历到元素相等,那么就需要合并了。例如 nums1[i]=nums2[j],那么它可以从任意一个数组中对应位置的前一个元素转移而来,我们选择其中的较大值:
f[i]=g[j]=max(f[i−1],g[j−1])+nums1​[i]

最终的答案即为 f[m−1]f[m-1]f[m−1] 与 g[n−1]g[n-1]g[n−1] 中的较大值

下面就要讨论,状态如何转移:
因为两个数组都是有序而且单调递增的。因此我们可以用双指针分别卡住两个数组的两端,从左向右去遍历去做选择。
1.使用两个指针 i 和 j 分别指向数组 nums1​ 和 nums2​ 的首元素;
2.每次在进行状态转移前,比较 nums1[i]] 的 nums2[j] 的大小关系。如果前者较小,那么对前者进行状态转移:
f[i]=f[i−1]+nums1​[i]
如果后者较小,那么对后者进行状态转移:
g[j]=g[j−1]+nums2​[j]
如果两者相等,那么同时进行状态转移:
f[i]=g[j]=max(f[i−1],g[j−1])+nums1​[i]

这样一来,我们就可以顺利地完成动态规划并得到答案。注意到在进行状态转移时,f[i]和 g[j]] 只会从 f[i−1 和 g[j−1] 转移而来,因此我们并不需要使用两个一维数组来存放动态规划的结果。我们可以仅使用两个变量 best1​ 和 best2 进行转移:
best1=best1+nums1[i]
best2=best2+nums2[j]
best1=best2=max⁡(best1,best2)+nums1[i]
它们的初始值均为 0。

代码演示

class Solution {
   
    public int maxSum(int[] nums1, int[] nums2) {
        final int MOD = 1000000007;
        long best1 = 0;
        long best2 = 0;
        //双指针
        int i = 0,j = 0;
        while(i < nums1.length || j < nums2.length){
            if(i < nums1.length && j < nums2.length){
                if(nums1[i] < nums2[j]){
                    best1 += nums1[i++];
                }else if(nums1[i] > nums2[j]){
                    best2 += nums2[j++];
                }else{
                    long best = Math.max(best1,best2) + nums1[i];
                    best1 = best;
                    best2 = best;
                    i++;
                    j++;
                }
            }else if(i < nums1.length){
                best1 += nums1[i++];
            }else if(j < nums2.length){
                best2 += nums2[j++];
            }
        }

        return (int)(Math.max(best1,best2) % MOD);
    }


}
更多推荐

如何在微软Edge浏览器上一键观看高清视频?

编者按:视频是当下最流行的媒体形式之一。但由于视频压缩、网络不稳定等原因,我们常常可以看到互联网上的很多视频其画面质量并不理想,尤其是在浏览器端,这极大地影响了观看体验。不过,近期微软Edge浏览器推出了一项新功能,一键就可以让浏览器中的视频变为高清版。这项神奇功能背后的技术秘诀是什么?今天,让我们一起来了解一下微软E

selenium学习

selenium模块和爬虫之间的关联便捷的获取网站中动态加载的数据便捷实现模拟登录什么是selenium模块基于浏览器自动化的一个模块selenium使用流程:-环境安装:pipinstallselenium-下载一个浏览器的驱动程序(谷歌浏览器)-下载路径:http://chromedriver.storage.go

C++版本的OpenCV实现二维图像的卷积定理(通过傅里叶变换实现二维图像的卷积过程,附代码!!)

C++版本的OpenCV库实现二维图像的卷积定理过程详解前言一、卷积定理简单介绍二、不同卷积过程对应的傅里叶变换过程1、“Same”卷积2、“Full”卷积3、“Valid”卷积三、基于OpenCV库实现的二维图像卷积定理四、基于FFTW库实现的二维图像卷积定理五、总结与讨论前言工作中用到许多卷积过程,需要转成C++代

SpringBoot的配置环境属性

SpringBoot的配置环境属性在本文中,我们将讨论SpringBoot的配置环境属性。我们将了解如何使用这些属性来配置我们的应用程序,以便在不同的环境中运行。我们还将了解如何使用SpringBoot的配置文件来管理这些属性。最后,我们将介绍一些最佳实践,以帮助您更有效地使用这些属性。理解SpringBoot的配置环

《C和指针》笔记28:可变参数和stdarg宏

可变参数列表可以通过宏来实现,这些宏定义于stdarg.h头文件,它是标准库的一部分。这个头文件声明了一个类型va_list和三个宏——va_start、va_arg和va_end。我们可以声明一个类型为va_list的变量,与这几个宏配合使用,访问参数的值。下面的程序使用这三个宏计算指定数量的值的平均值。注意参数列表

linux和windows选哪个?

linux和windows选哪个?每年在大学中都会有这么一批学生:沉浸在安装Linux系统,安装双系统,使用Linux系统看看电影,搞一搞炫酷的桌面效果。最后收获了啥?怕是啥也没有,命令学会了几个?能不能写shell?这些才有点价值。最近很多小伙伴找我,说想要一些linux学习资料,然后我根据自己从业十年经验,熬夜搞了

【第四阶段】kotlin语言的Map集合学习

1.Map集合的创建packageKotlin.Stage4funmain(){valmap=mapOf("java"to1,"kotlin"to2)//java代表键1代表值valmap2=mapOf(Pair("java",1),Pair("kotlin",2))//和上面写法等价}2.读取map的值方式1:使用[

多输入多输出 | MATLAB实现LSSVM最小二乘支持向量机多输入多输出

多输入多输出|MATLAB实现LSSVM最小二乘支持向量机多输入多输出目录多输入多输出|MATLAB实现LSSVM最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍MATLAB实现LSSVM最小二乘支持向量机多输入多输出1.data为数据集,10个输入特征,3个输出变量。2.main

安防监控视频系统EasyCVR+AI算法智能分析网关助力智慧校园建设

学生是祖国的未来,学校就是培育学生的地方。随着校园信息化建设的不断发展,信息服务在校园管理中的作用也越来越强。在保障学生安全与校园高效管理上,人工智能做出了极大贡献,旭帆科技安防监控系统/视频汇聚/云存储/AI智能视频分析平台EasyCVR基于互联网、大数据、云计算的智慧管理,为提高校园监管标准,推进学校信息化建设,打

redis桌面连接工具Another Redis Desktop Manager使用介绍

AnotherRedisDesktopManager是一种类似于navicat的数据库连接工具,专门用来连接redis,使用起来非常简单方便,在这里推荐给大家。没有用过这个软件的,首先通过下面的网盘链接下载AnotherRedisDesktopManager百度网盘redis下载地址https://pan.baidu.

基于图的基础推荐方式

文章目录1.基于图的基础推荐方式1.1链路预测(LinkPrediction)1.2什么是路径1.3基于路径的基础链路预测1.4图游走算法DeepWalk1.4.1Word2Vec1.4.2DeepWalk原理1.4.3DeepWalk代码示例1.5图游走算法Node2Vec1.5.1Node2Vec原理1.5.2No

热文推荐