[Algorithm Beating Diary] day33——1027. The longest arithmetic sequence, 446. Arithmetic sequence division II - subsequence

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;
    }
};

Guess you like

Origin blog.csdn.net/m0_69061857/article/details/134599602