forked from azl397985856/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
luzhipeng
committed
Nov 2, 2019
1 parent
fa78b13
commit e6ae6c7
Showing
4 changed files
with
218 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
problems/1218.longest-arithmetic-subsequence-of-given-difference.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
## 题目地址 | ||
|
||
https://leetcode-cn.com/problems/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 | ||
``` | ||
|
||
## 思路 | ||
|
||
最直观的思路是双层循环,我们暴力的枚举出以每一个元素为开始元素,以最后元素结尾的的所有情况。很明显这是所有的情况,这就是暴力法的精髓, 很明显这种解法会TLE(超时),不过我们先来看一下代码,顺着这个思维继续思考。 | ||
|
||
### 暴力法 | ||
|
||
```python | ||
def longestSubsequence(self, arr: List[int], difference: int) -> int: | ||
n = len(arr) | ||
res = 1 | ||
for i in range(n): | ||
count = 1 | ||
for j in range(i + 1, n): | ||
if arr[i] + difference * count == arr[j]: | ||
count += 1 | ||
|
||
if count > res: | ||
res = count | ||
|
||
return res | ||
``` | ||
### 动态规划 | ||
|
||
上面的时间复杂度是O(n^2), 有没有办法降低到O(n)呢?很容易想到的是空间换时间的解决方案。 | ||
|
||
我的想法是将`以每一个元素结尾的最长等差子序列的长度`统统存起来,即`dp[num] = maxLen` 这样我们遍历到一个新的元素的时候,就去之前的存储中去找`dp[num - difference]`, 如果找到了,就更新当前的`dp[num] = dp[num - difference] + 1`, 否则就是不进行操作(还是默认值1)。 | ||
|
||
这种空间换时间的做法的时间和空间复杂度都是O(n)。 | ||
|
||
|
||
## 关键点解析 | ||
|
||
- 将`以每一个元素结尾的最长等差子序列的长度`统统存起来 | ||
|
||
|
||
## 代码 | ||
|
||
```python | ||
# | ||
# @lc app=leetcode.cn id=1218 lang=python3 | ||
# | ||
# [1218] 最长定差子序列 | ||
# | ||
|
||
# @lc code=start | ||
|
||
|
||
class Solution: | ||
|
||
# 动态规划 | ||
def longestSubsequence(self, arr: List[int], difference: int) -> int: | ||
n = len(arr) | ||
res = 1 | ||
dp = {} | ||
for num in arr: | ||
dp[num] = 1 | ||
if num - difference in dp: | ||
dp[num] = dp[num - difference] + 1 | ||
|
||
return max(dp.values()) | ||
|
||
# @lc code=end | ||
``` | ||
|
||
## 相关题目 | ||
|
||
|
||
|
Oops, something went wrong.