力扣——2501. 数组中最长的方波

185 阅读1分钟

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

力扣——2501. 数组中最长的方波

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 。

提示:

  • 2 <= nums.length <= 105
  • 2 <= nums[i] <= 105

问题解析

这题虽然说的是子序列,但是题目说了“将子序列从小到大排序”,那么这题数组的先后顺序就不那么重要了。

  1. 我们可以直接把数组排好序,用从前往后遍历数组。
  2. 遍历到一个数后,判断这个数有没有整数的平方根,如果没有,把它的权重设为1.
  3. 如果有整数平方根,就看数组中有没有它的平方根,如果没有,也设为1.
  4. 如果数组中有他的平方根,它的权重设为它平方根的权重+1。
  5. 最长方波就是数组中的最大权重,如果小于2,输出-1.

AC代码

class Solution {
public:
    int longestSquareStreak(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size(),cnt=0;
        unordered_map<int,int>mymap;
        for(int i=0;i<n;i++)
        {
            int x=sqrt(nums[i]);
            if(x*x!=nums[i])
                mymap[nums[i]]=1;
            else
            {
                if(mymap.count(x))
                    mymap[nums[i]]=mymap[x]+1;
                else
                    mymap[nums[i]]=1;
                cnt=max(cnt,mymap[nums[i]]);
            }
        }
        if(cnt<2)return -1;
        return cnt;
    }
};