[1027. Longest Arithmetic Subsequence](https://leetcode.com/problems/longest-arithmetic-subsequence/)
### 題目描述
Given an array `nums` of integers, return *the length of the longest arithmetic subsequence in* `nums`.
**Note** that:
* A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
* A sequence `seq` is arithmetic if `seq[i + 1] - seq[i]` are all the same value (for `0 <= i < seq.length - 1`).
### 範例
**Example 1:**
```
Input: nums = [3,6,9,12]
Output: 4
Explanation: The whole array is an arithmetic sequence with steps of length = 3.
```
**Example 2:**
```
Input: nums = [9,4,7,2,10]
Output: 3
Explanation: The longest arithmetic subsequence is [4,7,10].
```
**Example 3:**
```
Input: nums = [20,1,15,3,10,5,8]
Output: 4
Explanation: The longest arithmetic subsequence is [20,15,10,5].
```
**Constraints**:
* 2 <= `nums.length` <= 1000
* 0 <= `nums[i]` <= 500
### 解答
#### Python
> 放假很閒,嘗試各種優化
> [name=Yen-Chi Chen][time=Fri, Jun 23, 2023]
```python=
class Solution:
def longestArithSeqLength(self, nums: List[int]) -> int:
n = len(nums)
if n <= 2:
return n
dp = [defaultdict(lambda: 1) for _ in range(n)]
ans = 0
for i in range(n):
for j in range(i):
diff = nums[i] - nums[j]
dp[i][diff] = dp[j][diff] + 1
ans = max(ans, dp[i][diff])
return ans
```
> Runtime 3391 ms Beats 39.18%
> [name=Yen-Chi Chen][time=Fri, Jun 23, 2023]
```python=
class Solution:
def longestArithSeqLength(self, nums: List[int]) -> int:
dp = {}
for i in range(len(nums)):
for j in range(i):
diff = nums[i] - nums[j]
if (j, diff) in dp:
dp[i, diff] = dp[j, diff] + 1
else:
dp[i, diff] = 2
return max(dp.values())
```
> Runtime 2825 ms Beats 80.4%
> [name=Yen-Chi Chen][time=Fri, Jun 23, 2023]
```python=
class Solution:
def longestArithSeqLength(self, nums: List[int]) -> int:
upper = max(nums)
n = len(nums)
ans = 0
for diff in range(-upper, upper + 1):
dp = defaultdict(int)
for num in nums:
dp[num] = dp[num - diff] + 1
ans = max(ans, max(dp.values()))
return ans
```
> Runtime 2055 ms Beats 90.59%
> [name=Yen-Chi Chen][time=Fri, Jun 23, 2023]
```python=
class Solution:
def longestArithSeqLength(self, nums: List[int]) -> int:
extent = max(nums) - min(nums)
n = len(nums)
ans = 2
for D in range(extent + 1):
if D * (ans - 1) >= extent:
break
for diff in [-D, D]:
dp = defaultdict(int)
for num in nums:
dp[num] = dp[num - diff] + 1
ans = max(ans, max(dp.values()))
return ans
```
> Runtime 215 ms Beats 100%
> [name=Yen-Chi Chen][time=Fri, Jun 23, 2023]
#### C++
``` cpp=
class Solution {
public:
const int MAX_NUM = 500;
int longestArithSeqLength(vector<int>& nums) {
ios_base::sync_with_stdio(0); cin.tie(0);
int n = nums.size();
int ans = 0;
// unordered_map<pair<int, int>, int, hash_pair> dp;
vector<vector<int>> dp(n + 10, vector(1000 + 10, 0));
// vector<unordered_map<int, int>> dp(n + 10);
for (int right = 1; right < n; right ++) {
for (int left = 0; left < right; left ++) {
int numDiff = nums[right] - nums[left] + MAX_NUM;
dp[right][numDiff] = dp[left][numDiff] + 1;
ans = max(ans, dp[right][numDiff]);
}
}
return ans + 1;
}
};
```
> [name=Jerry][time=23 June, 2023]
### Reference
[回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)