[LeetCode] 1027. Longest Arithmetic Subsequence 最長的等差數列



Given an array A of integers, return the length of the longest arithmetic subsequence in A.

Recall that a subsequence of A is a list A[i_1], A[i_2], ..., A[i_k] with 0 <= i_1 < i_2 < ... < i_k <= A.length - 1, and that a sequence B is arithmetic if B[i+1] - B[i] are all the same value (for 0 <= i < B.length - 1).

Example 1:

Input: A = [3,6,9,12]
Output: 4
Explanation:
The whole array is an arithmetic sequence with steps of length = 3.

Example 2:

Input: A = [9,4,7,2,10]
Output: 3
Explanation:
The longest arithmetic subsequence is [4,7,10].

Example 3:

Input: A = [20,1,15,3,10,5,8]
Output: 4
Explanation:
The longest arithmetic subsequence is [20,15,10,5].

Constraints:

  • 2 <= A.length <= 1000
  • 0 <= A[i] <= 500

這道題給了一個數組,讓找最長的等差數列的長度,暴力搜索的時間復雜度太大,這里就不考慮了。像這種玩數組,求極值的題,刷題老司機們應該很容易就反應出應該用動態規划 Dynamic Programming 來做,首先來考慮如何定義 DP 數組,最直接的就是用一個一維數組,其中 dp[i] 表示區間 [0, i] 中的最長等差數列的長度,但是這樣定義的話,很難找出狀態轉移方程。因為有些隱藏信息被我們忽略了,就是等差數列的相等的差值,不同的等差數列的差值可以是不同的,所以不包括這個信息的話將很難更新 dp 值。所以這里就需要一個二維數組,dp[i][j] 表示在區間 [0, i] 中的差值為j的最長等差數列的長度減1,這里減1是因為起始的數字並沒有被算進去,不過不要緊,最后再加回來就行了。還有一個需要注意的地方,由於等差數列的差值有可能是負數,而數組的下標不能是負數,所以需要處理一下,題目中限定了數組中的數字范圍為0到 500 之間,所以差值的范圍就是 -500 到 500 之間,可以給差值加上個 1000,這樣差值范圍就是 500 到 1500 了,二維 dp 數組的大小可以初始化為 nx2000。更新 dp 值的時候,先遍歷一遍數組,對於每個遍歷到的數字,再遍歷一遍前面的所有數字,算出差值 diff,再加上 1000,然后此時的 dp[i][diff] 可以賦值為 dp[j][diff]+1,然后用這個新的 dp 值來更新結果 res,最后別忘了 res 加1后返回,參見代碼如下:


class Solution {
public:
    int longestArithSeqLength(vector<int>& A) {
        int res = 0, n = A.size();
        vector<vector<int>> dp(n, vector<int>(2000));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                int diff = A[i] - A[j] + 1000;
                dp[i][diff] = dp[j][diff] + 1;
                res = max(res, dp[i][diff]);
            }
        }
        return res + 1;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1027


參考資料:

https://leetcode.com/problems/longest-arithmetic-subsequence/

https://leetcode.com/problems/longest-arithmetic-subsequence/discuss/274611/JavaC%2B%2BPython-DP


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM