Leecode刷题笔记---1218.最长定差子序列

             题目描述                                      

    给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr

中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。

子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除

任何元素而从 arr 派生出来的序列。

示例 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]。

#include <iostream>
#include <unordered_map>
#include <vector>
#include <fstream>

using namespace std;

class Solution {
public:
    int longestSubsequence(vector<int>& arr, int difference) {
        int ans = 0;
        int n = arr.size();
        unordered_map<int,int>m;
        vector<vector<int>>dp(n,vector<int>(2,0));             //dp[i][0]表示数组区间[0,i]第i个数不被选的情况下可以获得的最大子序列的长度值
         dp[0][1] = 1;                                         //dp[i][1]表示数组区间[0,i]第i个数被选的情况下可以获得的最大子序列的长度值
         m[arr[0]] = 0;
        for(int i = 1;i < arr.size();i++){
            dp[i][0] = max(dp[i - 1][1],dp[i - 1][0]);
            if(m.count(arr[i] - difference)){                     //如果上一个等差序列中的值存在于数组[0,i)中,则dp[i][1]的值为上一个序列数j的值+1 即:dp[j][1] + 1;
                dp[i][1] = dp[m[arr[i] - difference]][1] + 1;
            }
            else dp[i][1] = 1;
            m[arr[i]] = i;                                   //map 存放数组[0,i]的数值为键,它们的数组下标为键值
        }
    return max(dp[n - 1][0],dp[n - 1][1]);
    }
};

 动态规划代码优化:

class Solution {
public:
    int longestSubsequence(vector<int>& arr, int difference) {
        int ans = 0;
        unordered_map<int,int>dp;                  //dp[i] 表示以 arr[i] 为结尾的最长的等差子序列的长度
        for(auto v : arr){
            dp[v] = dp[v - difference] + 1;
            ans = max(ans,dp[v]);
        }
        return ans;
    }
};

main函数:

int main(){
        Solution  solve;
        const char *file = "source.txt";                         //存放用例 第一行存放数组 第二行存放diffrent值
        vector<int>arr;
        int diff = 0;
        ifstream  fin;
        fin.open(file);
        if(fin.is_open()){
            char ch; 
            int  item = 0;
            int row = 0;
            int minus = 1;
            while(fin.get(ch)){                                       //每次从文件中提取一个字符
                if(row % 2 == 0){                                        //如果是第0,2,4,6,8等偶数行    为arr数组
                if(ch == '[')continue;
                else if(ch == '-'){
                    minus = -1;
                }
                else if(isdigit(ch)){
                    item *= 10;
                    item += (ch - '0');
                }
                else if(ch == ',' || ch == ']'){                      //如果遇到‘,’或是‘]’ 则将数字存入中
                    if(minus == -1)arr.push_back(-item);
                    else arr.push_back(item);
                    item = 0;
                    minus = 1;
                }
                else if(ch == '\n'){
                    row++;
                }
            }
            else{                                              //如果是1,3,5 奇数行   为diffrent数值
                if(isdigit(ch)){
                    diff *= 10;
                    diff += (ch -'0');
                }
                else if(ch == '-'){
                    minus = -1;
                }
                else if(ch == '\n'){
                    row++;
                    if(row != 10){
                    cout<<"arr = [";
                    for(int i = 0;i < arr.size();i++){
                        cout<<arr[i];
                        if(i != arr.size()-1)cout<<",";
                    }
                    cout<<"]"<<endl;
                    }
                    if(minus == 1){
                    cout<<" diffrent = "<<diff<<endl;
                    }
                    else cout<<" diffrent = "<<-diff<<endl;
                    diff = minus * diff;
                    int ans = solve.longestSubsequence(arr,diff);
                    cout<<"ans = "<<ans<<endl;
                    diff = 0;
                    arr.clear();
                    item = 0;
                    minus = 1;
                }
            }
        }
        cout<<"arr = [";
         for(int i = 0;i < arr.size();i++){                                     //到达文件末尾
                        cout<<arr[i];
                        if(i != arr.size()-1)cout<<",";
        }
                    cout<<"]"<<endl;
                    if(minus == 1){
                    cout<<" diffrent = "<<diff<<endl;
                    }
                    else cout<<" diffrent = "<<-diff<<endl;
                    diff = minus * diff;
                    int ans = solve.longestSubsequence(arr,diff);
                    cout<<"ans = "<<ans<<endl;
        }
        fin.clear();
        fin.close();
        return 0;
}

 用例文件:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值