方法一,哈希表+枚举
- 构造哈希集合,记录出现过的数字
- 枚举遍历
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;}//更新最值,子序列的长度至少为2if (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;}
}