因此只要暴力枚举初始项,不断平方即可,至多循环 \log\log U 次,这里 U=max(\textit{nums})。
检查元素是否在数组中,可以用哈希表预处理。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10
classSolution: deflongestSquareStreak(self, nums: List[int]) -> int: ans, s = 0, set(nums) for x in s: cnt = 0 while x in s: cnt += 1 x *= x ans = max(ans, cnt) return ans if ans > 1else -1
[sol1-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funclongestSquareStreak(nums []int) (ans int) { set := map[int]bool{} for _, x := range nums { set[x] = true } for x := range set { cnt := 1 for x *= x; set[x]; x *= x { cnt++ } ans = max(ans, cnt) } if ans == 1 { return-1 } return }
funcmax(a, b int)int { if b > a { return b }; return a }
复杂度分析
时间复杂度:O(n\log\log U),其中 n 为 nums 的长度,U=max(\textit{nums})。
空间复杂度:O(n)。
方法二:记忆化搜索
[sol2-Python3]
1 2 3 4 5 6 7 8 9
classSolution: deflongestSquareStreak(self, nums: List[int]) -> int: s = set(nums) @cache defdfs(x: int) -> int: if x notin s: return0 return1 + dfs(x * x) ans = max(map(dfs, s)) return ans if ans > 1else -1
funclongestSquareStreak(nums []int) (ans int) { set := map[int]bool{} for _, x := range nums { set[x] = true } dp := map[int]int{} var f func(int)int f = func(x int)int { if !set[x] { return0 } if v, ok := dp[x]; ok { return v } dp[x] = 1 + f(x*x) return dp[x] } for x := range set { ans = max(ans, f(x)) } if ans == 1 { return-1 } return }
funcmax(a, b int)int { if b > a { return b }; return a }