数组中最长的方波

165 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情

问题描述

给你一个整数数组 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 。

提示:

  • 2 <= nums.length <= 10^5
  • 2 <= nums[i] <= 10^5

思路分析

题目会给我们一个整数数组 nums,我们需要计算其中 最长方波 的长度,最长方波指的是:

  • 子序列的长度至少为 2 ,并且
  • 将子序列从小到大排序 之后 ,除第一个元素外,每个元素都是前一个元素的 平方 。

如:[2,4,16],4是2的平方,16是4的平方。

我们可以按照下面步骤来做:

  • 1、使用哈希表将出现的元素记录起来

这里我们应该要注意到子序列是可以排序的,所以我们不用去在意每个元素所在的位置,只需要判断是否存在即可,因此我们可以先将所有出现过的元素使用哈希表记录起来,便于后面进行判断。

const map = {};
for(const num of nums) map[num] = 1;
  • 2、遍历数组,判断是否有元素可以和当前元素构成方波数组

遍历数组,判断给出数组中是否有其他可以构成方波数组的元素,如果有,则计算可以构成的最大长度。

let res = 0;
for(let i = 0; i < nums.length; i++){
    let num = nums[i];
    let max = 0;
    while(map[num]){
        max++;
        num *= num;
    }
    res = Math.max(res,max);
}
  • 3、返回计算结果

这里需要注意一下,方波数组要求子序列的长度至少为 2

return res < 2 ? -1 : res;

AC代码

/**
 * @param {number[]} nums
 * @return {number}
 */
 var longestSquareStreak = function(nums) {
    const map = {};
    for(const num of nums) map[num] = 1;
    let res = 0;
    for(let i = 0; i < nums.length; i++){
        let num = nums[i];
        let max = 0;
        while(map[num]){
            max++;
            num *= num;
        }
        res = Math.max(res,max);
    }
    return res < 2 ? -1 : res;
};

说在后面

本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。