You are given an integer array nums. A subsequence of nums is called a square streak if:
2, andReturn the length of the longest square streak in nums, or return -1 if there is no square streak.
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: nums = [4,3,6,16,8,2] Output: 3 Explanation: Choose the subsequence [4,16,2]. After sorting it, it becomes [2,4,16]. - 4 = 2 * 2. - 16 = 4 * 4. Therefore, [4,16,2] is a square streak. It can be shown that every subsequence of length 4 is not a square streak.
Example 2:
Input: nums = [2,3,5,6,7] Output: -1 Explanation: There is no square streak in nums so return -1.
Constraints:
2 <= nums.length <= 1052 <= nums[i] <= 105When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach finds the longest square streak by checking every possible sequence of numbers in the given list. For each number, we see if its square is also in the list, then the square of that number, and so on. We keep track of the longest sequence we find in this manner.
Here's how the algorithm would work step-by-step:
def longest_square_streak_brute_force(numbers):
longest_streak = -1
for starting_number in numbers:
current_number = starting_number
current_streak_length = 1
# Use a set for faster lookups
numbers_set = set(numbers)
# Check for the existence of squares.
while (current_number * current_number) in numbers_set:
current_number = current_number * current_number
current_streak_length += 1
# Need to update the longest streak
longest_streak = max(longest_streak, current_streak_length)
if longest_streak < 2:
return -1
else:
return longest_streakThe goal is to find the longest chain of numbers where each number is the square of the previous one. We can do this efficiently by checking if the square root of a number exists in our set of numbers.
Here's how the algorithm would work step-by-step:
def longest_square_streak(numbers):
number_set = set(numbers)
longest_streak_length = 0
for number in numbers:
# If the square root exists, it's part of a longer chain and cant start
if (number ** 0.5).is_integer() and int(number ** 0.5) in number_set:
continue
current_streak_length = 1
current_number = number
# Build the streak by squaring the number
while current_number * current_number in number_set:
current_number *= current_number
current_streak_length += 1
# Update the longest streak if needed
longest_streak_length = max(longest_streak_length, current_streak_length)
# If the longest streak is less than 2, no streak exists.
if longest_streak_length < 2:
return -1
return longest_streak_length| Case | How to Handle |
|---|---|
| Empty or null input array | Return 0 immediately as there's no streak possible. |
| Array with only one element | Return 0 because a streak requires at least two numbers where one is the square of the other. |
| Array contains negative numbers | Ignore negative numbers as they cannot be part of a square streak (squares are non-negative). |
| Array contains zero | Zero can only be part of a streak if it is paired with itself (0 * 0 = 0), which should be handled correctly, but can be an edge case to consider if zero is present only once |
| Array contains duplicate positive numbers | The longest streak should only consider unique numbers once so the solution must handle duplicates appropriately |
| Integer overflow when squaring large numbers | Use long data type or check for potential overflow before performing the square operation. |
| Array contains extreme boundary values (e.g., maximum integer) | Handle largest integer carefully when performing square or other mathematical operations to prevent overflow. |
| No valid square streak exists in the array | Return 0 when no valid streak is found during the iteration. |