思路有两个
- 层序遍历
- 先序遍历
下面是具体解法。以下代码都已提交通过。
解法一
层序遍历,基于队列。
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--
}