zoukankan      html  css  js  c++  java
  • [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为定差子序列结尾的子序列长度

    latex

    当前元素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

  • 相关阅读:
    关于MVC与MVP的理解
    使用JDBC连接数据库
    常见DML语句汇总
    java字符常量
    java中Map,List与Set的区别
    面向对象重写(override)与重载(overload)区别
    嵌入式系统的体系结构 图解
    使用webpack + momentjs时, 需要注意的问题
    联想电脑屏幕亮度无法调节
    树形数据构造
  • 原文地址:https://www.cnblogs.com/slowbirdoflsh/p/11659893.html
Copyright © 2011-2022 走看看