1027. The longest arithmetic sequence
1027. The longest arithmetic sequence
Topic description:
Give you an integer array nums
and return the length of the longest arithmetic subsequence in nums
a>.
Recall that the subsequence of nums
is a list nums[i1], nums[i2], ..., nums[ik]
, and 0 <= i1 < i2 < ... < ik <= nums.length - 1
. And if the values of seq[i+1] - seq[i]
( 0 <= i < seq.length - 1
) are all the same, then the sequence seq
is arithmetic.
Problem-solving ideas:
Algorithm idea:
1.
Status display:
For linear
dp
, we can use "experience + problem requirements" to define the state representation:
i.
End with a certain position, blah blah;
ii.
Start from a certain location, blah blah.
Here we choose a more commonly used method, ending with a certain position and combining the requirements of the topic to define a status representation:
dp[i]
means: "all subsequences ending with the element at
i
”, the length of the longest arithmetic sequence.
But there is a very fatal problem here, that is, we cannot determine what the arithmetic sequence at the end of
i
looks like . This will result in
We cannot derive the state transition equation, so the state representation we define needs to be able to determine an arithmetic sequence.
According to the characteristics of arithmetic sequences, we only need to know the last two elements of the sequence to determine what the sequence looks like. because
Therefore, we modify our status representation as:
dp[i][j]
means:
i
position and
j The element at position
is the longest arithmetic sequence among all the subsequences at the end
›length. Determine below
i < j
.
2.
State transfer process:
Suppose
nums[i] = b, nums[j] = c
, then the first element of this sequence is
. us
a = 2 * b - c
Based on
a
's situation:
a.
a
existence, below
k
,
a < From then on
i Positional element end result
The length of the arithmetic sequence, and then add the elements at the
j
position. So
dp[i][j] = dp[k][i] +
1
. Because there will be many
k
, we only need to leave
i
The nearest
k
is enough. So any longest one can be
k
for the end;
b.
a
existence, but is
b < a < c < a i=4>: At this time, the two elements are playing themselves,
dp[i][j] = 2 ;
c.
a
does not exist: At this time, only two elements can still play by themselves,
dp[i][j] = 2
.
In summary, the state transfer process can be discussed on a case-by-case basis.
Optimization point: We found that in the state transition process, we need to determine the subscript of the
a
element. So we can add all elements +
The subscripts are bound together and placed in the hash table. There are two strategies:
a.
is placed in the hash table before
dp
. This is possible, but the subscripts need to be formed into an array and put into the hash table. This way
The time complexity is high. I tried it for everyone and it timed out.
b.
One side
dp
, save one side. In this way, we only need to save the subscript of the nearest element, without saving the subscript array. But
Using this method, we first fix the second to last number in the traversal order, and then traverse the first to last number. That's it
You can change
nums[i] < when
i
is finished. a i=4> is thrown into the hash table.
3.
Initialization:
According to the actual situation, all positions can be initialized to
2
.
4.
Filling order:
a.
First fix the second number from the last;
b.
Then enumerate the last number.
5.
Reply:
Since we don’t know where the longest end is, we return the maximum value in the
dp
table.
Solution code:
class Solution {
public:
int longestArithSeqLength(vector<int>& nums) {
int n=nums.size();
vector<vector<int>>dp(n,vector<int>(n,2));
unordered_map<int,int>hash;
int ret=2;
hash[nums[0]]=0;
for(int i=1;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
int a=2*nums[i]-nums[j];
// int k=hash.count(a);
if(hash.count(a))
{
dp[i][j]=dp[hash[a]][i]+1;
}
ret=max(ret,dp[i][j]);
}
hash[nums[i]]=i;
}
return ret;
}
};
446. Arithmetic sequence division II - subsequence
Topic description:
Give you an integer array nums
and return all arithmetic subsequences in nums
< The number of a i=4>.
If there are at least three elements in a sequence and the difference between any two adjacent elements is the same, the sequence is called arithmetic sequence.
- Example,
[1, 3, 5, 7, 9]
, [7, 7, 7, 7]
和 [3, -1, -5, -9]
The capital is equal order.
- For another example,
[1, 1, 2, 5, 7]
is not an arithmetic sequence.
A subsequence in an array is a sequence obtained by deleting some elements from the array (or may not delete them).
- For example,
[2,5,10]
is a subsequence of . [1,2,1,2,4,1,5,10]
The question data guarantees that the answer is a 32-bit integer.
Problem-solving ideas:
Algorithm idea:
1.
Status display:
For linear
dp
, we can use "experience + problem requirements" to define the state representation:
i.
End with a certain position, blah blah;
ii.
Start from a certain location, blah blah.
Here we choose a more commonly used method, ending with a certain position and combining the requirements of the topic to define a status representation:
dp[i]
means: "all subsequences ending with the element at
i
”, the number of equal difference subsequences.
But there is a very fatal problem here, that is, we cannot determine what the arithmetic sequence at the end of
i
looks like . This will result in
We cannot derive the state transition equation, so the state representation we define needs to be able to determine an arithmetic sequence.
According to the characteristics of arithmetic sequences, we only need to know the last two elements of the sequence to determine what the sequence looks like. because
Therefore, we modify our status representation as:
dp[i][j]
means:
i
position and
j The element at position
is the number of equal-difference subsequences among all the subsequences at the end
number. Determine below
i < j
.
2.
State transfer process:
Suppose
nums[i] = b, nums[j] = c
, then the first element of this sequence is
. us
a = 2 * b - c
Based on
a
's situation:
a.
a
existence, below
k
,
a < Henceforth
i Arithmetic sequence of elements
The number of
dp[k][i]
, add
is still an arithmetic sequence. But there will be more here
comes out a new arithmetic sequence composed of elements at
k, i, j
position, so
dp[i][j] = dp[k][i]
+ 1
;
b.
Because
a
there may be many, and we need to add them all up.
综上,
dp[i][j] += dp[k][i] + 1
。
Optimization point: We found that in the state transition process, we need to determine the subscript of the
a
element. So we can put before dp
All elements + subscript arrays are bound together and placed in the hash table. Why do we need to save the subscript array here? It’s because we want to count the individual
Number, all subscripts need to be counted.
3.
Initialization:
There is no arithmetic sequence at the beginning, so the initialization
dp
table is
0
.
4.
Filling order:
a.
First fix the last number;
b.
Then enumerate the second to last number.
5.
Reply:
We want to count all arithmetic subsequences, so return the sum of all elements in the
dp
table.
Solution code:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n=nums.size();
vector<vector<int>>dp(n,vector(n,0));
unordered_map<long long,vector<int>>hash;
hash[nums[0]].push_back(0);
int sum=0;
for(int i=1;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
long long a=2*(long long)nums[i]-nums[j];
if(hash.count(a))
{
int length=hash[a].size();
for(int k=0;k<length;k++)
{
dp[i][j]+=dp[hash[a][k]][i]+1;
}
}
sum+=dp[i][j];
}
hash[nums[i]].push_back(i);
}
return sum;
}
};