贪心法:LeetCode1218 - 最长定差子序列

题目:

Given an integer array arr and an integer difference, return the length of the longest subsequence in arr which is an arithmetic sequence such that the difference between adjacent elements in the subsequence equals difference.

A subsequence is a sequence that can be derived from arr by deleting some or no elements without changing the order of the remaining elements.

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

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


思路:

首先想到的是利用和“最长上升子序列”差不多的动态规划方法, 从头到尾每个数扫描一次,dp[i]代表扫描到第i个数字时, 以该数字为结尾的最长等差子序列的长度, 但是对于每个数字, 都要重新扫描一遍前面的每一个数字, 寻找合适的(符合该数字减公差)且最大的(满足最长这一条件), 因此复杂度为O(n^2).

优化思路为, 利用"知道公差则确定上一个数字"这一原理进行优化, 可以利用哈希表一一对应的特性降低复杂度. dp[i]代表以数字i结尾的最长等差数列的长度. 复杂度为O(n)

哈希表初始化之后, 某个映射的结果默认为0?


题解:

普通算法

class Solution {
public:
    int longestSubsequence(vector<int> &arr, int difference) {
        int answer = 0;
        int dp[10000000]={0};
        for (int i=0;i<arr.size();++i) {
            for(int j=0;j<i;++j){
                if((arr[j]+difference)==arr[i]) dp[i]=dp[j]+1;
            }
        }
        return *max_element(dp,dp+arr.size())+1;
    }
};

优化算法

class Solution {
public:
    int longestSubsequence(vector<int> &arr, int difference) {
        int answer = 0;
        unordered_map<int, int> dp;  //<number, the longest length of this number's..>
        for (int v: arr) {
            dp[v] = dp[v - difference] + 1;
            answer = max(answer, dp[v]);
        }
        return answer;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值