LeetCode-1218 [最长定差子序列]

LeetCode-1218 最长定差子序列

  • 题目

给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。

子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。

  • 思路

    • 暴力搜索

      数组为arr,为了找到数组中的最长等差数列,可以遍历数组中的每一个值,最后对整个结果数组求max即可,如何求以该点为结尾的最长等差数列,以该点arr[i]为起始,反向遍历,查找arr[i]-differance是否存在,如果不存在,意味着不存在以该点位结尾的等差数列,直接置为1,如果存在一个arr[j],使得arr[j]+differance=arr[i](j<i),那么res[i]=res[j]+1

      优化:

      对于每个数字,都要反向遍历查找arr[i]-differance,我们可以使用map直接存储当前位置之前所有出现的数组中最长的等差子序列,

      eg:

      1 2 5 7

      differance=3

      遍历到5时,map中为【map[1]=1,map[2]=1】,此时直接判断map[5-3]是否等于0,不等于0代表有存在diferance的等差数列,此时等差数组长度增长1。map[5]=map[5-3]+1

    • 动态规划

      使用dp[arr[i]]存储以该点为结尾的最长等差序列的长度

      通过上述得知:

      \[dp[arr[i]]=dp[arr[i]-differance]+1 \]

      从左往右遍历,结果为$$max(dp)$$

  • Code

    • 暴力搜索(超时)
    class Solution {
    public:
        int longestSubsequence(vector<int>& arr, int difference) {
            vector<int> dp(arr.size());
            dp[0]=1;
            int max=1;
            for(int i=1;i<arr.size();i++){
                int j;
                for(j=i-1;j>=0;j--){
                    if(arr[j]+difference==arr[i]){
                        break;
                    }
                }
                if(j>=0){
                    dp[i]=dp[j]+1;
                    if(dp[i]>max){
                        max=dp[i];
                    }
                }
                else{
                    dp[i]=1;
                }
            }
            return max;
        }
    };
    
    • 优化
    class Solution {
    public:
        int longestSubsequence(vector<int>& arr, int difference) {
            vector<int> dp(arr.size());
            map<int,int> max_v;
            dp[0]=1;
            int max=1;
            max_v[arr[0]]=1;
            for(int i=1;i<arr.size();i++){
                int search=arr[i]-difference;
                if(max_v[search]!=0){
                    dp[i]=max_v[search]+1;
                    if(dp[i]>max){
                        max=dp[i];
                    }
                    max_v[arr[i]]=dp[i];
                }
                else{
                    dp[i]=1;
                    max_v[arr[i]]=dp[i];
                }
            }
            return max;
        }
    };
    
    • 动态规划
    class Solution {
    public:
        int longestSubsequence(vector<int>& arr, int difference) {
            unordered_map<int,int> dp;
            dp[arr[0]]=1;
            int res=1;
            for(int i=1;i<arr.size();i++){
                dp[arr[i]]=dp[arr[i]-difference]+1;
                res=max(dp[arr[i]],res);
            }
            return res;
        }
    };
    
posted @ 2021-11-05 11:06  流光之中  阅读(48)  评论(0编辑  收藏  举报