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

LeetCode 3176.求出最长好子序列 I:动态规划(DP)

【LetMeFly】3176.求出最长好子序列 I:动态规划(DP)

力扣题目链接:https://leetcode.cn/problems/find-the-maximum-length-of-a-good-subsequence-i/

给你一个整数数组 nums 和一个 非负 整数 k 。如果一个整数序列 seq 满足在范围下标范围 [0, seq.length - 2] 中存在 不超过 k 个下标 i 满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为  序列。

请你返回 nums 中  子序列 的最长长度

 

示例 1:

输入:nums = [1,2,1,1,3], k = 2

输出:4

解释:

最长好子序列为 [1,2,1,1,3] 。

示例 2:

输入:nums = [1,2,3,4,5,1], k = 0

输出:2

解释:

最长好子序列为 [1,2,3,4,5,1] 。

 

提示:

  • 1 <= nums.length <= 500
  • 1 <= nums[i] <= 109
  • 0 <= k <= min(nums.length, 25)

解题方法:动态规划

使用一个动态规划数组 d p dp dp,其中 d p [ i ] [ l ] dp[i][l] dp[i][l]代表数组前 i i i个元素的不超过 l l l个相邻不同的好子序列的最大长度。

初始值 d p [ i ] [ 0 ] = 1 dp[i][0]=1 dp[i][0]=1,其余值默认为 − 1 -1 1就行,转移方程:

d p [ i ] [ l ] = min ⁡ { d p [ i ] [ l ] d p [ j ] [ l ] + 1 if  n u m s [ i ] = n u m s [ j ] d p [ j ] [ l − 1 ] + 1 if  n u m s [ i ] ≠ n u m s [ j ] and  l > 0 dp[i][l] = \min \begin{cases} dp[i][l] & \\ dp[j][l] + 1 & \text{ if } nums[i]=nums[j]\\ dp[j][l - 1] + 1 & \text{ if } nums[i] \neq nums[j] \text{ and } l \gt 0 \end{cases} dp[i][l]=min dp[i][l]dp[j][l]+1dp[j][l1]+1 if nums[i]=nums[j] if nums[i]=nums[j] and l>0

三层循环,第一层用 i i i 0 0 0 l e n ( n u m s ) − 1 len(nums)-1 len(nums)1,第二层用 l l l 0 0 0 k k k,第三层用 j j j 0 0 0 i − 1 i-1 i1

  • 时间复杂度 O ( l e n ( n u m s ) 2 × k ) O(len(nums)^2\times k) O(len(nums)2×k)
  • 空间复杂度 O ( l e n ( n u m s ) × k ) O(len(nums)\times k) O(len(nums)×k)

更低复杂度请见下一题:求出最长好子序列 II

AC代码

C++
class Solution {
public:int maximumLength(vector<int>& nums, int k) {vector<vector<int>> dp(nums.size(), vector<int>(k + 1, -1));for (int i = 0; i < nums.size(); i++) {dp[i][0] = 1;for (int l = 0; l <= k; l++) {for (int j = 0; j < i; j++) {int diff = nums[i] != nums[j];if (l - diff >= 0) {dp[i][l] = max(dp[i][l], dp[j][l - diff] + 1);}}}}int ans = 0;for (int i = 0; i < nums.size(); i++) {for (int l = 0; l <= k; l++) {ans = max(ans, dp[i][l]);}}return ans;}
};
Python
from typing import Listclass Solution:def maximumLength(self, nums: List[int], k: int) -> int:dp = [[-1] * (k + 1) for _ in range(len(nums))]for i in range(len(nums)):dp[i][0] = 1for l in range(k + 1):for j in range(i):diff = int(nums[i] != nums[j])if l - diff >= 0:dp[i][l] = max(dp[i][l], dp[j][l - diff] + 1)return max(max(dp[i]) for i in range(len(nums)))

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/141992543


http://www.mrgr.cn/news/21436.html

相关文章:

  • 修改密码模块中对轮询接口响应用户失效问题的处理
  • 基于ASP+ACCESS的教师信息管理系统
  • 西方社会学理论教程(侯均生)笔记
  • SprinBoot+Vue应急信息管理系统的设计与实现
  • ctfshow-web入门-sql注入(web237-web240)insert 注入
  • 【人工智能学习笔记】2_数据处理基础
  • 超强台风摩羯逼近!或成大陆史上最强登陆台风,防御措施需到位
  • 深入了解 Lombok 的 `@SneakyThrows` 注解
  • Keysight U8031A DC power supply
  • DFS 算法:洛谷B3625迷宫寻路
  • C和指针:字符串
  • Python 从入门到实战10(流程控制-选择语句)
  • 2024 年高教社杯全国大学生数学建模竞赛B题第二问详细解题思路(终版)
  • Redis 缓存深度解析:穿透、击穿、雪崩与预热的全面解读
  • WebGL系列教程一(开篇)
  • isxdigit函数讲解 <ctype.h>头文件函数
  • 认知杂谈51
  • 【LeetCode】15.三数之和
  • Chrome下载视频的插件
  • 四个pdf软件分享,你更爱哪一款?