leetcode
leetcode 951 ~ 1000
最长等差数列

最长等差数列

难度:

标签:

题目描述

代码结果

运行时间: 534 ms, 内存: 25.3 MB


/*
  Solution Approach in Java Stream:
  1. The same approach as the Java solution can be applied using Java Streams for initialization and computation.
  2. Use Stream API to create and initialize the dp array with HashMaps.
  3. Use nested loops with Stream API operations to calculate the longest arithmetic subsequence.
*/
import java.util.*;
import java.util.stream.*;

public class Solution {
    public int longestArithSeqLength(int[] nums) {
        int n = nums.length;
        if (n <= 2) return n;
        int maxLength = 2;
        List<Map<Integer, Integer>> dp = IntStream.range(0, n)
            .mapToObj(i -> new HashMap<Integer, Integer>())
            .collect(Collectors.toList());
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                int diff = nums[i] - nums[j];
                dp.get(i).put(diff, dp.get(j).getOrDefault(diff, 1) + 1);
                maxLength = Math.max(maxLength, dp.get(i).get(diff));
            }
        }
        return maxLength;
    }
}

解释

方法:

本题解使用了动态规划的方法。定义一个字典`dp`,其中`dp[a][d]`表示以数字`a`结尾,公差为`d`的最长等差子序列的长度。遍历数组中的每个数字`a`,对于每个数字,再从之前遍历过的数字中选择一个数字`b`,计算公差`d = a - b`。如果这个公差在`dp[b]`中已存在,则说明可以在以`b`结尾,公差为`d`的子序列后追加`a`,形成更长的子序列。否则,以`a`和`b`可以形成一个新的长度为2的子序列。通过这种方式,可以更新`dp[a][d]`的值,并记录过程中出现的最大长度。

时间复杂度:

O(n^2)

空间复杂度:

O(n^2)

代码细节讲解

🦆
在解题的动态规划方法中,dp字典是如何初始化和更新的?特别是在遇到新的公差d时,dp[a][d]是如何设置的?
在动态规划的解法中,`dp`字典是用来存储以不同数值作为结尾,且具有不同公差的等差子序列的最大长度。具体到初始化,对于数组中每个新出现的数`a`,如果`a`不在`dp`中,就会为`a`创建一个新的空字典,这个字典将存储以`a`为结尾且具有各种公差`d`的子序列长度。当遇到新的公差`d`时,如果在`dp[b]`中已经存在公差`d`,则`dp[a][d]`被设置为`dp[b][d] + 1`,表示在以`b`为结尾的等差子序列后添加`a`,形成更长的序列。如果`dp[b]`中不存在公差`d`,则表示`a`和`b`可以形成一个新的长度为2的等差子序列,此时`dp[a][d]`被初始化为2。
🦆
为何在遍历元素b时,需要特别判断`b == a`并跳过处理?这样的处理对算法的正确性有什么影响?
在遍历元素`b`时,特别判断`b == a`并跳过处理是为了避免将元素`a`与其自身进行比较。如果不做这种判断,那么当`a`和`b`相同时,公差`d`将计算为0,这会导致以`a`为结尾的等差子序列错误地考虑自身作为序列的一部分。这种自引用会造成算法结果的不准确,因为等差数列的定义要求至少包含两个不同的元素。因此,这样的处理确保了算法的正确性,使得每个等差数列至少包含两个独立的元素。
🦆
如果数组`nums`中含有重复的数字,这种方法处理重复数字时是否会有问题?例如,处理公差计算时可能出现的除0错误。
在这种方法中,处理数组`nums`中重复的数字不会导致除0错误或其他问题。算法在计算公差`d = a - b`时,如果`a`与`b`相同,确实会产生0的公差,但这并不会引起除0错误,因为这里没有进行除法运算。相反,公差为0的情况意味着在数组中存在重复的数字,这些数字可以形成公差为0的等差数列。因此,算法能够正确处理重复数字,只要遵循逻辑确保不重复计算同一元素对自身的公差即可。

相关问题