[leetcode 周赛 157] 1218 最长定差子序列

1218 Longest Arithmetic Subsequence of Given Difference 最长定差子序列

问题描述

给你一个整数数组 arr 和一个整数 difference,请你找出 arr 中所有相邻元素之间的差等于给定 difference 的等差子序列,并返回其中最长的等差子序列的长度。

  • 示例 1:

输入:arr = [1,2,3,4], difference = 1
输出:4
解释:最长的等差子序列是 [1,2,3,4]。

  • 示例 2:

输入:arr = [1,3,5,7], difference = 1
输出:1
解释:最长的等差子序列是任意单个元素。

  • 示例 3:

输入:arr = [1,5,7,8,5,3,4,2,1], difference = -2
输出:4
解释:最长的等差子序列是 [7,5,3,1]。

  • 提示:

    • 1 <= arr.length <= 10^5
    • -10^4 <= arr[i], difference <= 10^4

思路

  • 读题
    顺序读取每个元素, 通过difference来筛选一个等差序列

    动态规划

    可以使用动态规划的思路, 建立两个函数:

  • F(k) 前k个元素中最长定差子序列的长度
  • G(num) 以元素num为定差子序列结尾的子序列长度

当前元素num所在子序列长度等于前一个序列数num-difference所在子序列的长度+1
G[num] = G[num-difference]+1
如果num之前没有出现num-difference元素 则G[num-difference]为0

  • 实例
    arr = [1,5,7,8,5,3,4,2,1], difference = -2
步骤 已输入数 当前元素 最长定差子序列长度
1 1 G[1]=G[1-(-2)]+1=G[3]+1=0+1 =1 F[1]=1
2 1 5 G[5]=G[5-(-2)]+1=G[7]+1=0+1 =1 F[2]=1
3 1 5 7 G[7]=G[7-(-2)]+1=G[9]+1=0+1 =1 F[3]=1
4 1 5 7 8 G[8]=G[8-(-2)]+1=G[10]+1=0+1=1 F[4]=1
5 1 5 7 8 5 G[5]=G[5-(-2)]+1=G[7]+1=1+1 =2 F[5]=1
6 1 5 7 8 5 3 G[3]=G[3-(-2)]+1=G[5]+1=2+1 =3 F[6]=1
7 1 5 7 8 5 3 4 G[4]=G[4-(-2)]+1=G[6]+1=0+1 =1 F[7]=1
8 1 5 7 8 5 3 4 2 G[2]=G[2-(-2)]+1=G[4]+1=1+1 =2 F[8]=1
9 1 5 7 8 5 3 4 2 1 G[1]=G[1-(-2)]+1=G[3]+1=3+1 =4 F[9]=1
  • 图解

代码实现

动态规划

class Solution {
     public int longestSubsequence(int[] arr, int difference) {
         // res 输出结果 最长子序列长度
        int res = 0;
        // maps 存放键值出现时, 自己所在的定差子序列长度
        Map<Integer, Integer> maps = new HashMap<>(arr.length);

        // 相当于一个每次向右加+1的变长窗口
        for (int a : arr) {
            // 每个元素第一次出现时 初始值置为0
            if (!maps.containsKey(a)) {
                maps.put(a, 0);
            }
            // 该元素在子序列中前一个元素 可能出现的子序列长度(没有则为0)
            int pre = maps.get(a-difference) == null ? 0 : maps.get(a-difference);
            // 该元素子序列长度 比较自己所在序列以及前一个元素所在序列+1
            int na = Math.max(maps.get(a), pre+1);
            // 获取当前最大子序列长度
            res = Math.max(na, res);
            // 设置该元素所在子序列长度
            maps.put(a, na);
            //System.out.println(String.format("pre:%d na:%d res:%d maps:%s", pre, na, res, maps));
        }

        return res;
    }
}

参考资源

第 157 场周赛 全球排名
【算法实况】体验使用 iPadOS 打算法竞赛 - 力扣周赛 - LeetCode Weekly 157

原文地址:https://www.cnblogs.com/slowbirdoflsh/p/11659893.html

时间: 2024-08-23 23:39:01

[leetcode 周赛 157] 1218 最长定差子序列的相关文章

[leetcode 周赛 157] 1217 玩筹码

1217 Play With Chips 玩筹码 题目描述 数轴上放置了一些筹码,每个筹码的位置存在数组 chips 当中. 你可以对 任何筹码 执行下面两种操作之一(不限操作次数,0 次也可以): 将第 i 个筹码向左或者右移动 2 个单位,代价为 0. 将第 i 个筹码向左或者右移动 1 个单位,代价为 1. 最开始的时候,同一位置上也可能放着两个或者更多的筹码. 返回将所有筹码移动到同一位置(任意位置)上所需要的最小代价. 示例 1: 输入:chips = [1,2,3] 输出:1 解释:

[leetcode 周赛 157] 1219 黄金矿工

1219 Path with Maximum Gold 黄金矿工 问题描述 你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注.每个单元格中的整数就表示这一单元格中的黄金数量:如果该单元格是空的,那么就是 0. 为了使收益最大化,矿工需要按以下规则来开采黄金: 每当矿工进入一个单元,就会收集该单元格中的所有黄金. 矿工每次可以从当前位置向上下左右四个方向走. 每个单元格只能被开采(进入)一次. 不得开采(进入)黄金数目为 0 的单元

leetcode——Longest Common Prefix 最长公共前缀(AC)

Write a function to find the longest common prefix string amongst an array of strings. 其实做起来会感觉很简单,需要注意的是要考虑效率的问题,毕竟可能是很长的字符串数组,所以可以考虑选取所有字符串中最短的那个来首先进行比较,因为最长公共子串肯定不会大于其长度,这样避免了字符串之间长度差异很大造成的效率损失,然后每次比较之后最长公共子串的长度也永远不会大于最短的那个字符串,只会不变或减小,只要遍历字符串数组,挨个

[LeetCode] Longest Uncommon Subsequence I 最长非共同子序列之一

Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subseq

最长回文子序列(不连续)以及最长回文子串(连续)

整理了一下关于回文子序列和回文子串的程序. 其中(1)和(2)是采用动态规划的思想写出的回文子序列的程序,这种子序列就是在原始的串中可以不连续,比如对于那种要求删除几个字符来得到最长的回文字符串的题就是这种情况. 比如caberbaf.  最长的子序列是5 abeba 或者abrba.而子串最长只有1 (3)(4)(5)都是最长子串的求法.(3)是暴力求解,(4)是改进的暴力求解.(5)采用的是动态规划的方法. 1 #include <iostream> 2 #include <stri

【动态规划+高精度】mr360-定长不下降子序列

[题目大意] 韵哲君发现自己的面前有一行数字,当她正在琢磨应该干什么的时候,这时候,陈凡老师从天而降,走到了韵哲君的身边,低下头,对她耳语了几句,然后飘然而去. 陈凡老师说了什么呢,陈凡老师对韵哲君说了这些话:“还记得我传授给你的不下降子序列吗?你现在只要找出一定长度的不下降子序列的种数,你就完成任务了.” 你也来做做这个活动吧? 输入格式 Input Format 第一行有两个整数N(0<N<=200),M(0<M<=20): N表示给出多少个整数,M表示给出的定长: 第二行有N

【模板】最长不下降子序列

====接力dalao完成==== 前文链接:(CSP-S RP++!) 对前文的一些补充: 首先清楚最长不下降子序列是一个递增但是允许不同位元素相等的序列.而最长上升子序列则是一个单调递增的序列. 而两者都是子序列,所以子序列的长度一定小于等于原序列.且子序列在原序列的位置不一定连续. 这个O(nlogn)的算法使用的是贪心的思想. 为了帮助理解,请与以下代码对比阅读: #include<iostream> using namespace std; int a[1000001],dp[100

[codevs2185]最长公共上升子序列

试题描述 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序列了.小沐沐说,对于两个串A,B,如果它们都包含一段位置不一定连续的数字,且数字是严格递增的,那么称这一段数字是两个串的公共上升子串,而所有的公共上升子串中最长的就是最长公共上升子串了.奶牛半懂不懂,小沐沐要你来告诉奶牛什么是最长公共上升子串.不过,只要告诉奶牛它的长度就可以了. 输入 第一行N,表示A,B的长度.第二行,串A.第三行,串B.

最长回文子序列

题目:给你一个字符串,求它的最长回文子序列,比如"bbbab" 最长回文子序列是"bbbb" 所以返回4,,"abab"最长子序列是"aba"或者"bab" 所以返回3 思路:和之前做的几道dp不同,,,也是我不够变通,,打dp表的时候总习惯左上到右下的顺序,但是这个顺序却固化了我的思维,忽略了对于题解本身含义的理解....... 这个题从下到上开始打表,最重要的是它的含义,,,知道dp[i][j]意味着什