Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/2246.html
2246. Longest Path With Different Adjacent Characters
- Difficulty: Hard.
- Related Topics: Array, String, Tree, Depth-First Search, Graph, Topological Sort.
- Similar Questions: Diameter of Binary Tree, Longest Univalue Path, Choose Edges to Maximize Score in a Tree.
Problem
You are given a tree (i.e. a connected, undirected graph that has no cycles) rooted at node 0
consisting of n
nodes numbered from 0
to n - 1
. The tree is represented by a 0-indexed array parent
of size n
, where parent[i]
is the parent of node i
. Since node 0
is the root, parent[0] == -1
.
You are also given a string s
of length n
, where s[i]
is the character assigned to node i
.
Return the length of the **longest path in the tree such that no pair of adjacent nodes on the path have the same character assigned to them.**
Example 1:
Input: parent = [-1,0,0,1,1,2], s = "abacbe"
Output: 3
Explanation: The longest path where each two adjacent nodes have different characters in the tree is the path: 0 -> 1 -> 3. The length of this path is 3, so 3 is returned.
It can be proven that there is no longer path that satisfies the conditions.
Example 2:
Input: parent = [-1,0,0,0], s = "aabc"
Output: 3
Explanation: The longest path where each two adjacent nodes have different characters is the path: 2 -> 0 -> 3. The length of this path is 3, so 3 is returned.
Constraints:
-
n == parent.length == s.length
-
1 <= n <= 105
-
0 <= parent[i] <= n - 1
for alli >= 1
-
parent[0] == -1
-
parent
represents a valid tree. -
s
consists of only lowercase English letters.
Solution
-
class Solution { public int longestPath(int[] parent, String s) { // for first max length int[] first = new int[s.length()]; Arrays.fill(first, 0); // for second max length int[] second = new int[s.length()]; Arrays.fill(second, 0); // for number of children for this node int[] children = new int[s.length()]; Arrays.fill(children, 0); for (int i = 1; i != s.length(); i++) { // calculate all children for each node children[parent[i]]++; } // for traversal from leafs to root LinkedList<Integer> st = new LinkedList<>(); // put all leafs for (int i = 1; i != s.length(); i++) { if (children[i] == 0) { st.add(i); } } // traversal from leafs to root while (!st.isEmpty()) { // fetch current node int i = st.pollLast(); // if we in root - ignore it if (i == 0) { continue; } if (--children[parent[i]] == 0) { // decrease number of children by parent node and if number of children st.add(parent[i]); } // is equal 0 - our parent became a leaf // if letters isn't equal if (s.charAt(parent[i]) != s.charAt(i)) { // fetch maximal path from node int maxi = 1 + Math.max(first[i], second[i]); // and update maximal first and second path from parent if (maxi >= first[parent[i]]) { second[parent[i]] = first[parent[i]]; first[parent[i]] = maxi; } else if (second[parent[i]] < maxi) { second[parent[i]] = maxi; } } } // fetch answer int ans = 0; for (int i = 0; i != s.length(); i++) { ans = Math.max(ans, first[i] + second[i]); } return ans + 1; } }
-
# 2246. Longest Path With Different Adjacent Characters # https://leetcode.com/problems/longest-path-with-different-adjacent-characters/ class Solution: def longestPath(self, parent: List[int], s: str) -> int: n = len(parent) graph = defaultdict(list) res = 0 for x, y in enumerate(parent): if y == -1 or s[x] == s[y]: continue graph[y].append(x) graph[x].append(y) @cache def go(node, prev): nonlocal res path = [1] for nei in graph[node]: if nei != prev: path.append(go(nei, node) + 1) path.sort(reverse = 1) if len(path) == 1: res = max(res, path[0]) else: res = max(res, path[0] + path[1] - 1) return path[0] for i in range(n): go(i, -1) return res
-
function longestPath(parent: number[], s: string): number { const n = parent.length; let graph = Array.from({ length: n }, v => []); for (let i = 1; i < n; i++) { graph[parent[i]].push(i); } let ans = 0; function dfs(x: number): number { let maxLen = 0; for (let y of graph[x]) { let len = dfs(y) + 1; if (s.charAt(x) !== s.charAt(y)) { ans = Math.max(maxLen + len, ans); maxLen = Math.max(len, maxLen); } } return maxLen; } dfs(0); return ans + 1; }
-
class Solution { public: int longestPath(vector<int>& parent, string s) { int n = parent.size(); vector<int> g[n]; for (int i = 1; i < n; ++i) { g[parent[i]].push_back(i); } int ans = 0; function<int(int)> dfs = [&](int i) -> int { int mx = 0; for (int j : g[i]) { int x = dfs(j) + 1; if (s[i] != s[j]) { ans = max(ans, mx + x); mx = max(mx, x); } } return mx; }; dfs(0); return ans + 1; } };
-
func longestPath(parent []int, s string) int { n := len(parent) g := make([][]int, n) for i := 1; i < n; i++ { g[parent[i]] = append(g[parent[i]], i) } ans := 0 var dfs func(int) int dfs = func(i int) int { mx := 0 for _, j := range g[i] { x := dfs(j) + 1 if s[i] != s[j] { ans = max(ans, x+mx) mx = max(mx, x) } } return mx } dfs(0) return ans + 1 } func max(a, b int) int { if a > b { return a } return b }
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).