package jianzhi
import (
"container/list"
"fmt"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func levelOrder(root *TreeNode) []int {
if root == nil{
return []int{}
}
var queue = list.New()
queue.PushBack(root)
var res []int
for ; queue.Len() != 0;{
curNode := queue.Front().Value.(*TreeNode)
queue.Remove(queue.Front())
res = append(res,curNode.Val)
fmt.Println(curNode.Val)
if curNode.Left != nil{
queue.PushBack(curNode.Left)
}
if curNode.Right != nil{
queue.PushBack(curNode.Right)
}
}
return res
}
/*
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
*/
func mirrorTree(root *TreeNode) *TreeNode {
if root == nil{
return nil
}
var queue = list.New()
queue.PushBack(root)
for ; queue.Len() != 0;{
curNode := queue.Front().Value.(*TreeNode)
queue.Remove(queue.Front())
tmp := curNode.Left
curNode.Left = curNode.Right
curNode.Right = tmp
if curNode.Left != nil{
queue.PushBack(curNode.Left)
}
if curNode.Right != nil{
queue.PushBack(curNode.Right)
}
}
return root
}
func TestMirrorTree(){
var root = TreeNode{1,&TreeNode{2,&TreeNode{4,nil, nil},&TreeNode{5,nil,nil}},
&TreeNode{3,&TreeNode{6,nil,nil},&TreeNode{7,nil,nil}}}
levelOrder(&root)
res := mirrorTree(&root)
levelOrder(res)
}
/*
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
*/
func isSymmetric(root *TreeNode) bool {
if root == nil{
return true
}
//原层级遍历结点:
var queue = list.New()
queue.PushBack(root)
var nodes []int
for ; queue.Len() != 0;{
curNode := queue.Front().Value.(*TreeNode)
queue.Remove(queue.Front())
if curNode == nil{
nodes = append(nodes,-1)
continue
}
nodes = append(nodes,curNode.Val)
queue.PushBack(curNode.Left)
queue.PushBack(curNode.Right)
}
//翻转
queue = list.New()
queue.PushBack(root)
var mirNodes []int
for ; queue.Len() != 0;{
curNode := queue.Front().Value.(*TreeNode)
queue.Remove(queue.Front())
if curNode == nil{
mirNodes = append(mirNodes,-1)
continue
}
tmp := curNode.Left
curNode.Left = curNode.Right
curNode.Right = tmp
mirNodes = append(mirNodes,curNode.Val)
queue.PushBack(curNode.Left)
queue.PushBack(curNode.Right)
}
fmt.Println(nodes,mirNodes)
for index, node := range nodes{
if node != mirNodes[index]{
return false
}
}
return true
}
func TestisSymmetric(){
var root = TreeNode{1,&TreeNode{2,&TreeNode{3,nil,nil},&TreeNode{3,nil,nil}},
&TreeNode{2,&TreeNode{3,nil,nil},&TreeNode{3,nil,nil}}}
res := isSymmetric(&root)
fmt.Println(res)
}
/*
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
例如:给定二叉树 [3,9,20,null,null,15,7],return 3
使用递归,当左右子树为空时返回1,
*/
func maxDepth(root *TreeNode) int {
var lDep,rDep = 0,0
if root == nil{
return 0
}
if root.Left == nil && root.Right == nil{
return 1
}
lDep += maxDepth(root.Left)
rDep += maxDepth(root.Right)
if lDep > rDep{
return lDep + 1
}
return rDep + 1
}
/*
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
左子树《当前结点《右子树
(1)先(根)序遍历(根左右)
(2)中(根)序遍历(左根右)
(3)后(根)序遍历(左右根
中序遍历后 得到一个递增排序的数组 return arr[len-k]
*/
func kthLargest(root *TreeNode, k int) int {
if root == nil{
return -1
}
var arr []int
midPrint(root,&arr)
if k <=0 || k >len(arr){
return -1
}
return arr[len(arr)-k]
}
func midPrint(root *TreeNode, arr *[]int){
if root == nil{
return
}
midPrint(root.Left,arr)
*arr = append(*arr,root.Val)
midPrint(root.Right,arr)
}
func TestKthLargest(){
var root = TreeNode{3,&TreeNode{1,nil,&TreeNode{2,nil,nil}},
&TreeNode{4,nil,nil}}
res := kthLargest(&root,1)
fmt.Println(res)
}
/*
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
找到两个结点的祖先所有结点 并用hash保存,
*/
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || p == nil || q == nil{
return nil
}
var (
pAns []*TreeNode = []*TreeNode{p}
qAns []*TreeNode = []*TreeNode{q}
)
for parentNode := findParentNode(root,p,nil);parentNode != nil;parentNode = findParentNode(root,parentNode,nil){
pAns = append(pAns,parentNode)
}
for parentNode := findParentNode(root,q,nil);parentNode != nil;parentNode = findParentNode(root,parentNode,nil){
qAns = append(qAns,parentNode)
}
for _, pan := range pAns{
for _, qan := range qAns{
if pan == qan{
return pan
}
}
}
return nil
}
func findParentNode(root,node,parent *TreeNode) *TreeNode{
if root == nil{
return nil
}
if root == node{
return parent
}
res := findParentNode(root.Left,node,root)
if res == nil{
res = findParentNode(root.Right,node,root)
}
return res
}
func TestParentNode(){
var p = TreeNode{24,nil,nil}
var q = TreeNode{27,nil,&p}
var root = TreeNode{1,&TreeNode{2,&TreeNode{3,nil,nil},&p},
&TreeNode{7,&TreeNode{11,nil,nil},&q}}
parent := findParentNode(&root,&p,nil)
fmt.Println(parent.Val)
ans := lowestCommonAncestor(&root, &p, &q)
if ans != nil{
fmt.Println(ans.Val)
}else{
fmt.Println("nil")
}
}
/*
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder) == 0 || len(inorder) == 0{
return nil
}
var node = TreeNode{preorder[0],nil,nil}
var index = 0
for i, inVal := range inorder{
if inVal == preorder[0]{
index = i
break
}
}
node.Left = buildTree(preorder[1:index+1],inorder[:index])
node.Right = buildTree(preorder[index+1:],inorder[index+1:])
return &node
}
func TestBuildTree(){
res:= buildTree([]int{3,9,20,15,7},[]int{9,3,15,20,7})
levelOrder(res)
}
/*
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
*/
//使用递归的思想 先在A中找到B的根节点,再用递归判断每个结点的值是否相等
func isSubStructure(A *TreeNode, B *TreeNode) bool {
if A == nil || B== nil{
return false
}
if A.Val == B.Val{
if isEqualTree(A,B){
return true
}
}
res := isSubStructure(A.Left,B)
if !res{
res = isSubStructure(A.Right, B)
}
return res
}
func isEqualTree(A *TreeNode, B *TreeNode) bool{
if B == nil{
return true
}else if A == nil {
return false
}
if A.Val == B.Val{
return isEqualTree(A.Right,B.Right) && isEqualTree(A.Left,B.Left)
}
return false
}
//按照层次遍历的顺序 首先找到跟 子树根节点相同的结点,然后 isEqualTree也用层次遍历 一层层 判断 每个结点是否一样。
func isSubStructure2(A *TreeNode, B *TreeNode) bool {
if A == nil || B== nil{
return false
}
queue :=list.New()
queue.PushBack(A)
for queue.Len() != 0{
node := queue.Front().Value.(*TreeNode)
queue.Remove(queue.Front())
if node.Val == B.Val{
if isEqualTree2(node,B){
return true
}
}
if node.Left != nil{
queue.PushBack(node.Left)
}
if node.Right != nil{
queue.PushBack(node.Right)
}
}
return false
}
func isEqualTree2(A *TreeNode, B *TreeNode) bool{
if B == nil{
return true
}else if A == nil {
return false
}
queueA :=list.New()
queueB :=list.New()
queueA.PushBack(A)
queueB.PushBack(B)
for queueB.Len() != 0 && queueA.Len() != 0{
nodeA := queueA.Front().Value.(*TreeNode)
nodeB := queueB.Front().Value.(*TreeNode)
queueA.Remove(queueA.Front())
queueB.Remove(queueB.Front())
if nodeB == nil{
continue
}else if nodeA == nil{
return false
}
if nodeA.Val != nodeB.Val{
return false
}
queueA.PushBack(nodeA.Left)
queueA.PushBack(nodeA.Right)
queueB.PushBack(nodeB.Left)
queueB.PushBack(nodeB.Right)
}
if queueB.Len() != 0{
return false
}
return true
}
func TestSubStruct(){
var tree = TreeNode{10,&TreeNode{12,&TreeNode{6,nil,nil},&TreeNode{8,nil,nil}},
&TreeNode{1,nil,nil}}
var tree2 = TreeNode{10,&TreeNode{12,&TreeNode{6,nil,nil},&TreeNode{8,nil,nil}},nil}
res := isSubStructure2(&tree,&tree2)
fmt.Println(res)
}
/*
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
3
1 5
0 2 4 6
后序:0 2 1 4 6 5 3
第一个降序的就是根节点
*/
// todo
func verifyPostorder(postorder []int) bool {
if len(postorder) <= 1{
return true
}
var rootIndex = 0
for index:=1;index<len(postorder);index++{
if postorder[index] < postorder[index-1]{
rootIndex = index
break
}
}
for _,val := range postorder[:rootIndex]{
if val > postorder[rootIndex]{
return false
}
}
for _,val := range postorder[rootIndex+1:]{
if val < postorder[rootIndex]{
return false
}
}
return verifyPostorder(postorder[rootIndex:])
}
/*
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
*/
func pathSum(root *TreeNode, target int) [][]int {
if root == nil{
return [][]int{}
}
var res [][]int
path(root,0,target,[]int{},&res)
return res
}
func path(root *TreeNode, sum int, target int, arr []int ,res *[][]int) {
if root == nil{
return
}
sum += root.Val
arr = append(arr,root.Val)
if root.Left == nil && root.Right == nil{
if sum == target{
tmp := append([]int{},arr...)
*res = append(*res,tmp)
}
return
}
path(root.Left,sum,target,arr,res)
path(root.Right,sum,target,arr,res)
}
func TestPathSum(){
var tree = TreeNode{5,&TreeNode{4,&TreeNode{11,&TreeNode{7,nil,nil},
&TreeNode{2,nil,nil}},nil},
&TreeNode{8,&TreeNode{13,nil,nil},
&TreeNode{4,&TreeNode{5,nil,nil},&TreeNode{1,nil,nil}}}}
res := pathSum(&tree, 22)
fmt.Println(res)
}
剑指offer 二叉树相关 Go实现
最新推荐文章于 2022-10-06 14:13:45 发布