【特殊子序列 DP】力扣2501. 数组中最长的方波

给你一个整数数组 nums 。如果 nums 的子序列满足下述条件,则认为该子序列是一个 方波 :

子序列的长度至少为 2 ,并且

将子序列从小到大排序 之后 ,除第一个元素外,每个元素都是前一个元素的 平方 。

返回 nums 中 最长方波 的长度,如果不存在 方波 则返回 -1 。

子序列 也是一个数组,可以由另一个数组删除一些或不删除元素且不改变剩余元素的顺序得到。

示例 1 :

输入:nums = 4,3,6,16,8,2

输出:3

解释:选出子序列 4,16,2 。排序后,得到 2,4,16

  • 4 = 2 * 2.
  • 16 = 4 * 4.
    因此,4,16,2 是一个方波.
    可以证明长度为 4 的子序列都不是方波。

示例 2 :

输入:nums = 2,3,5,6,7

输出:-1

解释:nums 不存在方波,所以返回 -1 。

回溯法

cpp 复制代码
class Solution {
public:
    int longestSquareStreak(vector<int>& nums) {
        unordered_set<long long> s(nums.begin(), nums.end());
        unordered_map<long long, int> memo;
        function<int(long long)> dfs = [&](long long x) -> int{
            if(s.find(x) == s.end()) return 0;
            if(memo.find(x) != memo.end()) return memo[x];

            memo[x] = 1 + dfs(x * x);
            return memo[x];
        };
        int ans = 0;
        for(int num : nums){
            ans = max(ans, dfs(num));
        }
        return ans >= 2 ? ans : -1;
    }
};

时间复杂度:O(n) ,其中 n 为 nums 的长度。至多有 O(n) 个状态。
空间复杂度:O(n)

我们可以使用回溯的方法,我们可以遍历数组的每一个元素,然后对他们进行回溯,他们会不断以O(1)的时间复杂度去寻找无序集合s里面是否有他们的平方。如果找到有他们的平方的数,那么就储存最长方波到memox中,并且与ans比较。在后面遍历过程中,如果回溯查找到memo中已经有缓存,那么就会直接返回memo。


动态规划

cpp 复制代码
class Solution {
public:
    int longestSquareStreak(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<int> dp(nums.back() + 1);
        int ans = 0;
        for(int x : nums){
            dp[x] = 1;
            int t = sqrt(x);
            if(t * t == x) dp[x] = dp[t] + 1;
            ans = max(ans, dp[x]);
        }
        return ans >= 2 ? ans : -1;
    }
};

我们可以采用先排序然后进行动态规划的方式,这样运行速度较快。我们定义nums中的元素为x,我们定义dpx为该元素为结尾的最大波长。要进行状态转移的前提是元素x进行根号后是整数(真实运算时),如果判断x进行根号后是整数,那么我们可以列出状态转移方程dp[x] = dp[t] + 1,并且与ans进行比对。

相关推荐
find1star3 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
迅翼SwiftWing4 小时前
编队系列(总)|固定翼编队如何实现稳定飞行?通信架构、协同算法与工程约束深度解析
算法·架构
LB21124 小时前
力扣160 21 86
算法·leetcode·职场和发展
小智老师PMP5 小时前
2026深度解析|PMP第八版与NPDP核心侧重点本质区别(管理类证书怎么选)
开发语言·分布式·算法·职场和发展·产品经理
HugoStudio_SWAN5 小时前
洛谷 B4450 / B3867 / B3923 智慧购物、储蓄与做题——从程序到生活
c++·学习·程序人生·算法·生活
a187927218315 小时前
【算法】动态规划第二篇:双序列 DP 三课——继承、计步与断链
算法·leetcode·动态规划·dp·回溯·暴力·算法讲解
江畔柳前堤6 小时前
前台·中台·后台:2026年AI原生时代的架构全景图
开发语言·人工智能·算法·机器学习·架构·scala·ai-native
文心快码BaiduComate7 小时前
2026 OPC x AI Coding 趋势案例交流会圆满落幕:一个人就一支研发团队
算法
ACM-moran7 小时前
条件显化(二分单峰函数+构造数列)
算法·推公式·整数三分
闻缺陷则喜何志丹7 小时前
【栈 运算系统】P3719 [AHOI2017初中组] rexp|普及+
c++·算法··洛谷·运算系统