mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-24 02:14:00 +08:00
113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
package leetcode
|
|
|
|
import (
|
|
"github.com/halfrost/LeetCode-Go/structures"
|
|
)
|
|
|
|
// TreeNode define
|
|
type TreeNode = structures.TreeNode
|
|
|
|
/**
|
|
* Definition for a binary tree node.
|
|
* type TreeNode struct {
|
|
* Val int
|
|
* Left *TreeNode
|
|
* Right *TreeNode
|
|
* }
|
|
*/
|
|
|
|
// 解法一 递归
|
|
func isCousins(root *TreeNode, x int, y int) bool {
|
|
if root == nil {
|
|
return false
|
|
}
|
|
levelX, levelY := findLevel(root, x, 1), findLevel(root, y, 1)
|
|
if levelX != levelY {
|
|
return false
|
|
}
|
|
return !haveSameParents(root, x, y)
|
|
}
|
|
|
|
func findLevel(root *TreeNode, x, level int) int {
|
|
if root == nil {
|
|
return 0
|
|
}
|
|
if root.Val != x {
|
|
leftLevel, rightLevel := findLevel(root.Left, x, level+1), findLevel(root.Right, x, level+1)
|
|
if leftLevel == 0 {
|
|
return rightLevel
|
|
}
|
|
return leftLevel
|
|
}
|
|
return level
|
|
}
|
|
|
|
func haveSameParents(root *TreeNode, x, y int) bool {
|
|
if root == nil {
|
|
return false
|
|
}
|
|
if (root.Left != nil && root.Right != nil && root.Left.Val == x && root.Right.Val == y) ||
|
|
(root.Left != nil && root.Right != nil && root.Left.Val == y && root.Right.Val == x) {
|
|
return true
|
|
}
|
|
return haveSameParents(root.Left, x, y) || haveSameParents(root.Right, x, y)
|
|
}
|
|
|
|
// 解法二 BFS
|
|
type mark struct {
|
|
prev int
|
|
depth int
|
|
}
|
|
|
|
func isCousinsBFS(root *TreeNode, x int, y int) bool {
|
|
if root == nil {
|
|
return false
|
|
}
|
|
queue := []*TreeNode{root}
|
|
visited := [101]*mark{}
|
|
visited[root.Val] = &mark{prev: -1, depth: 1}
|
|
|
|
for len(queue) > 0 {
|
|
node := queue[0]
|
|
queue = queue[1:]
|
|
depth := visited[node.Val].depth
|
|
if node.Left != nil {
|
|
visited[node.Left.Val] = &mark{prev: node.Val, depth: depth + 1}
|
|
queue = append(queue, node.Left)
|
|
}
|
|
if node.Right != nil {
|
|
visited[node.Right.Val] = &mark{prev: node.Val, depth: depth + 1}
|
|
queue = append(queue, node.Right)
|
|
}
|
|
}
|
|
if visited[x] == nil || visited[y] == nil {
|
|
return false
|
|
}
|
|
if visited[x].depth == visited[y].depth && visited[x].prev != visited[y].prev {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 解法三 DFS
|
|
func isCousinsDFS(root *TreeNode, x int, y int) bool {
|
|
var depth1, depth2, parent1, parent2 int
|
|
dfsCousins(root, x, 0, -1, &parent1, &depth1)
|
|
dfsCousins(root, y, 0, -1, &parent2, &depth2)
|
|
return depth1 > 1 && depth1 == depth2 && parent1 != parent2
|
|
}
|
|
|
|
func dfsCousins(root *TreeNode, val, depth, last int, parent, res *int) {
|
|
if root == nil {
|
|
return
|
|
}
|
|
if root.Val == val {
|
|
*res = depth
|
|
*parent = last
|
|
return
|
|
}
|
|
depth++
|
|
dfsCousins(root.Left, val, depth, root.Val, parent, res)
|
|
dfsCousins(root.Right, val, depth, root.Val, parent, res)
|
|
}
|