// Time: O(nlogn) // Space: O(n) // hash table class Solution { public: int longestSquareStreak(vector<int>& nums) { set<int64_t> sorted_nums(cbegin(nums), cend(nums)); unordered_set<int64_t> squares; for (const auto& x : sorted_nums) { if (x % 4 < 2) { // squared_num % 4 in [0, 1] squares.emplace(x); } } int result = 0; for (const auto& x : sorted_nums) { int cnt = 1; for (int64_t square = x * x; squares.count(square); squares.erase(square), square *= square) { ++cnt; } result = max(result, cnt); } return result != 1 ? result : -1; } }; // Time: O(nlogn) // Space: O(n) // dp class Solution2 { public: int longestSquareStreak(vector<int>& nums) { sort(begin(nums), end(nums)); unordered_map<int, int> dp; int result = 0; for (const auto& x : nums) { const int sqrt_x = static_cast<int>(sqrt(x)); if (sqrt_x * sqrt_x == x) { dp[x] = dp[sqrt_x] + 1; } else { dp[x] = 1; } result = max(result, dp[x]); } return result != 1 ? result : -1; } };