leetcode 100. 相同的树

152 阅读2分钟

题目链接

思路有两个

  • 层序遍历
  • 先序遍历

下面是具体解法。以下代码都已提交通过。

解法一

层序遍历,基于队列。

func isSameTree(p *TreeNode, q *TreeNode) bool {
    if p == nil && q == nil {
        return true
    }
    qe := NewQueue()
    // 两树根节点入队
    qe.Push(p)
    qe.Push(q)
    for !qe.IsEmpty() {
        // 出队两树的某子树的根节点
        np := qe.Pop().(*TreeNode)
        nq := qe.Pop().(*TreeNode)
        // 比较
        if np == nil && nq == nil {
            continue
        }
        if np == nil && nq != nil {
            return false
        }
        if np != nil && nq == nil {
            return false
        }
        if np.Val != nq.Val {
            return false
        }
        // 入队左子树
        qe.Push(np.Left)
        qe.Push(nq.Left)
        // 入队右子树
        qe.Push(np.Right)
        qe.Push(nq.Right)
    }
    return true
}

type Queue struct {
	list *SinglyLinkedList
}

func NewQueue() *Queue {
	return &Queue{
		list: &SinglyLinkedList{},
	}
}

func (o *Queue) IsEmpty() bool {
	return o.list.Len() == 0
}

func (o *Queue) Push(v interface{}) {
	o.list.AddToTail(v)
}

func (o *Queue) Peek() interface{} {
	if o.IsEmpty() {
		panic("Queue is empty")
	}
	return o.list.Head().V
}

func (o *Queue) Pop() interface{} {
	if o.IsEmpty() {
		panic("Queue is empty")
	}
	node := o.list.Head()
	o.list.RemoveHead()
	return node.V
}

// 单链表节点
type SLLNode struct {
	V interface{}
	Next *SLLNode
}

// 单链表
type SinglyLinkedList struct {
	head *SLLNode
	tail *SLLNode // 尾节点。使得在尾部添加节点的时间复杂度是O(1)
        size int
}

func (o *SinglyLinkedList) Len() int {
        return o.size
}

func (o *SinglyLinkedList) AddToHead(v interface{}) {
	o.head = &SLLNode{
		V: v,
        Next: o.head,
	}
	if o.tail == nil {
		o.tail = o.head
	}
        o.size++
}

func (o *SinglyLinkedList) Head() *SLLNode {
	return o.head
}

func (o *SinglyLinkedList) RemoveHead() {
	if o.head == nil {
		panic("SinglyLinkedList. head is nil")
	}
	o.head = o.head.Next
	if o.head == nil {
		o.tail = nil
	}
        o.size--
}

func (o *SinglyLinkedList) AddToTail(v interface{}) {
	node := &SLLNode{
		V: v,
	}
	if o.tail != nil {
		o.tail.Next = node
		o.tail = node
	} else {
		o.head = node
        o.tail = node
	}
        o.size++
}

解法二

先序遍历,递归实现。

func isSameTree(p *TreeNode, q *TreeNode) bool {
    if p == nil && q == nil {
        return true
    }
    if p != nil && q == nil {
        return false
    }
    if p == nil && q != nil {
        return false
    }
    if p.Val != q.Val {
        return false
    }
    if !isSameTree(p.Left, q.Left) ||
       !isSameTree(p.Right, q.Right) {
        return false
    }
    return true
}

解法三

先序遍历,迭代,基于栈。

func isSameTree(p *TreeNode, q *TreeNode) bool {
    if p == nil && q == nil {
        return true
    }
    sk := NewStack()
    sk.Push(q)
    sk.Push(p)
    for !sk.IsEmpty() {
        np := sk.Peek().(*TreeNode)
        sk.Pop()
        nq := sk.Peek().(*TreeNode)
        sk.Pop()
        if np == nil && nq == nil {
            continue
        }
        if np == nil && nq != nil {
            return false
        }
        if np != nil && nq == nil {
            return false
        }
        if np.Val != nq.Val {
            return false
        }
        sk.Push(nq.Right)
        sk.Push(np.Right)
        sk.Push(nq.Left)
        sk.Push(np.Left)
    }
    return true
}

type Stack struct {
	list *SinglyLinkedList
}

func NewStack() *Stack {
	return &Stack{
		list: &SinglyLinkedList{},
	}
}

func (o *Stack) Len() int {
	return o.list.Len()
}

func (o *Stack) IsEmpty() bool {
	return o.list.Len() == 0
}

func (o *Stack) Push(v interface{}) {
	o.list.AddToHead(v)
}

func (o *Stack) Peek() interface{} {
	if o.IsEmpty() {
		panic("Stack is empty")
	}
	return o.list.Head().V
}

func (o *Stack) Pop() {
	if o.IsEmpty() {
		panic("Stack is empty")
	}
	o.list.RemoveHead()
}

// 单链表节点
type SLLNode struct {
	V interface{}
	Next *SLLNode
}

// 单链表
type SinglyLinkedList struct {
	head *SLLNode
        size int
}

func (o *SinglyLinkedList) Len() int {
        return o.size
}

func (o *SinglyLinkedList) AddToHead(v interface{}) {
	o.head = &SLLNode{
		V: v,
        Next: o.head,
	}
        o.size++
}

func (o *SinglyLinkedList) Head() *SLLNode {
	return o.head
}

func (o *SinglyLinkedList) RemoveHead() {
	if o.head == nil {
		panic("SinglyLinkedList. head is nil")
	}
	o.head = o.head.Next
        o.size--
}