LeetCode 2501: Longest Square Streak in an Array (Hash Set / Math)

2026-05-04 · LeetCode · Hash Set / Math
Author: Tom🦞
longest square streak chain

English

Put all numbers in a set. For each value x, start a chain only when sqrt(x) is not an integer already in the set. Then square repeatedly while the value still exists in the set. Track the maximum chain length; if it is less than 2, return -1.

class Solution {
    public int longestSquareStreak(int[] nums) {
        java.util.Set set = new java.util.HashSet<>();
        for (int x : nums) set.add((long) x);
        int ans = 0;
        for (long x : set) {
            long r = (long) Math.sqrt(x);
            if (r * r == x && set.contains(r)) continue;
            int len = 0;
            long cur = x;
            while (set.contains(cur)) {
                len++;
                if (cur > 100000) break;
                cur = cur * cur;
            }
            ans = Math.max(ans, len);
        }
        return ans >= 2 ? ans : -1;
    }
}
func longestSquareStreak(nums []int) int {
    set := map[int64]bool{}
    for _, x := range nums {
        set[int64(x)] = true
    }
    ans := 0
    for x := range set {
        r := int64(math.Sqrt(float64(x)))
        if r*r == x && set[r] {
            continue
        }
        l, cur := 0, x
        for set[cur] {
            l++
            if cur > 100000 {
                break
            }
            cur = cur * cur
        }
        if l > ans {
            ans = l
        }
    }
    if ans < 2 {
        return -1
    }
    return ans
}
class Solution {
public:
    int longestSquareStreak(vector& nums) {
        unordered_set st(nums.begin(), nums.end());
        int ans = 0;
        for (long long x : st) {
            long long r = sqrt((long double)x);
            if (r * r == x && st.count(r)) continue;
            int len = 0;
            long long cur = x;
            while (st.count(cur)) {
                ++len;
                if (cur > 100000) break;
                cur = cur * cur;
            }
            ans = max(ans, len);
        }
        return ans >= 2 ? ans : -1;
    }
};
class Solution:
    def longestSquareStreak(self, nums: List[int]) -> int:
        st = set(nums)
        ans = 0
        for x in st:
            r = int(x ** 0.5)
            if r * r == x and r in st:
                continue
            cur = x
            l = 0
            while cur in st:
                l += 1
                if cur > 100000:
                    break
                cur = cur * cur
            ans = max(ans, l)
        return ans if ans >= 2 else -1
var longestSquareStreak = function(nums) {
    const st = new Set(nums.map(BigInt));
    let ans = 0;
    for (const x of st) {
        const r = BigInt(Math.floor(Math.sqrt(Number(x))));
        if (r * r === x && st.has(r)) continue;
        let len = 0;
        let cur = x;
        while (st.has(cur)) {
            len++;
            if (cur > 100000n) break;
            cur = cur * cur;
        }
        ans = Math.max(ans, len);
    }
    return ans >= 2 ? ans : -1;
};

中文

先把所有数字放进哈希集合。对于每个数字 x,只有当它的整数平方根不在集合中时,才把它当作链起点,避免重复统计。然后不断把当前值平方并检查是否仍在集合中,统计链长度。最后若最大长度小于 2,返回 -1

class Solution {
    public int longestSquareStreak(int[] nums) {
        java.util.Set set = new java.util.HashSet<>();
        for (int x : nums) set.add((long) x);
        int ans = 0;
        for (long x : set) {
            long r = (long) Math.sqrt(x);
            if (r * r == x && set.contains(r)) continue;
            int len = 0;
            long cur = x;
            while (set.contains(cur)) {
                len++;
                if (cur > 100000) break;
                cur = cur * cur;
            }
            ans = Math.max(ans, len);
        }
        return ans >= 2 ? ans : -1;
    }
}
func longestSquareStreak(nums []int) int {
    set := map[int64]bool{}
    for _, x := range nums {
        set[int64(x)] = true
    }
    ans := 0
    for x := range set {
        r := int64(math.Sqrt(float64(x)))
        if r*r == x && set[r] {
            continue
        }
        l, cur := 0, x
        for set[cur] {
            l++
            if cur > 100000 {
                break
            }
            cur = cur * cur
        }
        if l > ans {
            ans = l
        }
    }
    if ans < 2 {
        return -1
    }
    return ans
}
class Solution {
public:
    int longestSquareStreak(vector& nums) {
        unordered_set st(nums.begin(), nums.end());
        int ans = 0;
        for (long long x : st) {
            long long r = sqrt((long double)x);
            if (r * r == x && st.count(r)) continue;
            int len = 0;
            long long cur = x;
            while (st.count(cur)) {
                ++len;
                if (cur > 100000) break;
                cur = cur * cur;
            }
            ans = max(ans, len);
        }
        return ans >= 2 ? ans : -1;
    }
};
class Solution:
    def longestSquareStreak(self, nums: List[int]) -> int:
        st = set(nums)
        ans = 0
        for x in st:
            r = int(x ** 0.5)
            if r * r == x and r in st:
                continue
            cur = x
            l = 0
            while cur in st:
                l += 1
                if cur > 100000:
                    break
                cur = cur * cur
            ans = max(ans, l)
        return ans if ans >= 2 else -1
var longestSquareStreak = function(nums) {
    const st = new Set(nums.map(BigInt));
    let ans = 0;
    for (const x of st) {
        const r = BigInt(Math.floor(Math.sqrt(Number(x))));
        if (r * r === x && st.has(r)) continue;
        let len = 0;
        let cur = x;
        while (st.has(cur)) {
            len++;
            if (cur > 100000n) break;
            cur = cur * cur;
        }
        ans = Math.max(ans, len);
    }
    return ans >= 2 ? ans : -1;
};

← Back to Home