🔍 找到数组里的“节奏感”:最长等差子序列

有没有遇到过这样的数字序列:
[3, 6, 9, 12]

你一看就知道:哇,这是一个节奏分明、步步递进的等差数列!

那么问题来了:**如果数组不是这么整齐呢?**比如:

ini 复制代码
int[] arr = {3, 6, 9, 7, 12, 15, 4, 8};

请你找出这个数组中最长的等差子序列,也就是说,一段步伐一致的"节奏段子",长度最长是多少?

🧠 解题思路:把每一对数字看作"舞伴"

我们想象一下,一个数组里的每两个数字 array[j]array[i](其中 j < i)就是在跳舞。

只要这两个数字的"步伐差"(也就是 array[i] - array[j])一样,我们就可以把它们串成一段节奏。

于是我们用一个 Map<Integer, Integer>[] dp 数组来记录每一个以 i 结尾、以某个"步伐差值"跳起来的最长序列长度。

动态规划结构设计

ini 复制代码
Map<Integer, Integer>[] dp = new Map[array.length];
  • dp[i] 表示以 array[i] 结尾的等差子序列,Map 的键是差值 diff,值是长度。
  • 初始化每个 dp[i] 为一个新的 HashMap。

然后,我们从 i = 0n - 1,每次再枚举 j = 0i - 1,做如下事情:

差值计算:

c 复制代码
int diff = array[i] - array[j];

🎯 状态转移:

  • 如果 dp[j] 中没有这个差值,我们从头开始这段舞步(长度为2)。
  • 否则,我们延续这个差值的节奏,长度 +1。
ini 复制代码
if (!dp[j].containsKey(diff)) {
    dp[i].put(diff, 2);
} else {
    dp[i].put(diff, dp[j].get(diff) + 1);
}

更新全局最大值:

ini 复制代码
globalMax = Math.max(globalMax, dp[i].get(diff));

最终代码

ini 复制代码
import java.util.HashMap;
import java.util.Map;

public class LongestArithSequence {

    public int longestArithSequence(int[] array){
        if(array == null || array.length < 2) return 0;

        int globalMax = 0;
        Map<Integer, Integer>[] dp = new Map[array.length];

        for(int i = 0; i < array.length; i++) {
            dp[i] = new HashMap<>();
            for(int j = 0; j < i; j++) {
                int diff = array[i] - array[j];
                dp[i].put(diff, dp[j].getOrDefault(diff, 1) + 1);
                globalMax = Math.max(globalMax, dp[i].get(diff));
            }
        }

        return globalMax;
    }

    public static void main(String[] args) {
        LongestArithSequence las = new LongestArithSequence();
        int[] array = {3, 6, 9, 7, 12, 15, 4, 8};
        System.out.println("Longest arithmetic subsequence length: " + las.longestArithSequence(array));
    }
}

🧩 小结:这道题考察了什么?

  • ✅ 动态规划的状态定义能力
  • ✅ 对"差值"这个维度的抽象能力
  • ✅ 选择合适的数据结构(数组 + HashMap)来降低复杂度

思考

  1. 如果是等比数列,思路要怎么变?
  2. 如何打印出最长的那一段子序列?
  3. 如果数组非常长,比如上万条数据,如何进一步优化空间?
相关推荐
SimonKing3 分钟前
告别传统读写!RandomAccessFile让你的Java程序快人一步
java·后端·程序员
Little-Hu5 分钟前
QML TextEdit组件
java·服务器·数据库
Edingbrugh.南空1 小时前
Flink ClickHouse 连接器数据读取源码深度解析
java·clickhouse·flink
NE_STOP1 小时前
SpringBoot--简单入门
java·spring
DoraBigHead1 小时前
小哆啦解题记——映射的背叛
算法
Heartoxx1 小时前
c语言-指针与一维数组
c语言·开发语言·算法
hqxstudying1 小时前
Java创建型模式---原型模式
java·开发语言·设计模式·代码规范
孤狼warrior2 小时前
灰色预测模型
人工智能·python·算法·数学建模
京东云开发者2 小时前
京东零售基于国产芯片的AI引擎技术
算法
Dcs2 小时前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java