#3715
Sum of Perfect Square Ancestors
HardArrayHash TableMathTreeDepth-First SearchCountingNumber TheoryHash MapArray
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n²) | O(n) |
| Space | O(1) | O(n) |
💡
Intuition
Time O(n)Space O(n)
Use prime factorization to determine the square-free kernel of each node's value. Maintain a count of these kernels while traversing the tree.
⚙️
Algorithm
3 steps- 1Step 1: Precompute the square-free representation of each node's value using prime factorization.
- 2Step 2: Perform a DFS traversal, maintaining a count of the square-free kernels encountered.
- 3Step 3: For each node, check if its kernel matches any ancestor's kernel and update the count accordingly.
solution.py30 lines
1from collections import defaultdict
2import math
3
4def prime_factors(n):
5 factors = defaultdict(int)
6 for i in range(2, int(math.sqrt(n)) + 1):
7 while n % i == 0:
8 factors[i] += 1
9 n //= i
10 if n > 1:
11 factors[n] += 1
12 return frozenset(p for p, exp in factors.items() if exp % 2 == 1)
13
14def sum_of_perfect_square_ancestors(n, edges, nums):
15 graph = [[] for _ in range(n)]
16 for u, v in edges:
17 graph[u].append(v)
18 graph[v].append(u)
19 total = 0
20 def dfs(node, parent, kernels):
21 nonlocal total
22 current_kernel = prime_factors(nums[node])
23 total += kernels[current_kernel]
24 kernels[current_kernel] += 1
25 for neighbor in graph[node]:
26 if neighbor != parent:
27 dfs(neighbor, node, kernels)
28 kernels[current_kernel] -= 1
29 dfs(0, -1, defaultdict(int))
30 return totalℹ
Complexity note: Each node is processed once, and we use a map to track kernels, leading to linear complexity.
- 1Perfect squares relate to prime factorization and square-free kernels.
- 2Efficient ancestor tracking can reduce redundant calculations.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.