方法一,哈希表+枚举
- 构造哈希集合,记录出现过的数字
- 枚举遍历
import java.util.HashSet;
import java.util.Set;
class Solution {
public int longestSquareStreak(int[] nums) {
//构造哈希表集合,记录出现过的数字,转long型,避免求平方后int越界
Set<Long> set = new HashSet<>();
for (long num : nums) {
set.add(num);
}
int maxLen = -1;
//直接枚举,依据题意找到了子序列后从小到达排序,因此无需排序,无需判断索引大小
for (long num : nums) {
int subLen = 1;
num *= num;
//若包含平方数,继续枚举
while (set.contains(num)) {
subLen++;
num *= num;
}
//更新最值,子序列的长度至少为2
if (subLen > 1 && subLen > maxLen) {
maxLen = subLen;
}
}
return maxLen;
}
}
方法二,排序+二分
- 先排序
- 遍历时,如果nums[i]*nums[i]>nums[n-1]时,可以直接跳出循环
- 在查找是否存在当前值的平方时,可以采用二分法查找,因为只需要查找是否存在,所以可以用库函数Arrays.binarySearch(int[] nums, int target),返回值idx小于0,表示不存在
import java.util.Arrays;
class Solution {
public int longestSquareStreak(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
int ans = -1;
for (int i = 0; i < n; i++) {
if (nums[i] * nums[i] > nums[n - 1]) {
break;
}
int idx = i, cnt = 0;
while (idx >= 0) {
idx = Arrays.binarySearch(nums, nums[idx] * nums[idx]);
if (idx >= 0) {
cnt++;
}
}
ans = Math.max(ans, cnt + 1);
}
return ans > 1 ? ans : -1;
}
}