1、题目
2、题解
看到题目的第一瞬间,脑子里想,这要是给个数组多简单啊,可惜给的指针,leetcode真的永远都不让我如意,坏家伙(哼!)
因为想到了数组,而对称的二叉树中序遍历的结果往往也是对称的,所以脑海中的第一个解法是对树进行中序遍历,将节点的值存到数组里,然后对数组进行检查,查看其中的值是否对称(下标之和相加等于数组长度的两个数相等即可)。
按照这种思路解答的过程中发现如下注意点:1)当左右子树仅一方为空时,为空的那方需要一个标志来标识(因为节点范围 >= 1,所以选择 -1 作为标识)万万没想到这个方法在提交时居然出现了错误结果 [5,4,1,null,1,null,4,2,null,2,null]。
二叉树明显不对称,手动中序遍历,发现结果是对称的,突然明白现在的二叉树节点中的值是随意的,存在数组中的数字对称但实际树并不对称的情况,不愧是测试用例,涵盖到方方面面了(突然很好奇测试用例是怎么得到的)。
之前还想到过用栈进行遍历的方法,跟上面思路类型,这下看起来也不行了,那就只能保证在值相等的同时位置绝对对称,想要这样的话似乎只能两个指针严格遍历了,一个选则左子树遍历另一个一定选择右子树遍历,实现代码如下:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
var symmetryTree func(r1, r2 *TreeNode) bool
symmetryTree = func(r1, r2 *TreeNode) bool{
if r1==nil && r2==nil {
return true
}else if r1==nil || r2==nil{
return false
}else{
return r1.Val==r2.Val && symmetryTree(r1.Left, r2.Right) && symmetryTree(r1.Right, r2.Left)
}
}
return symmetryTree(root, root)
}
提交结果如下
这个执行用时,只能说不愧是递归。想要降低时间复杂度再结合题目的进阶提示,要将递归更改为迭代,同样需要两个指针,同时创建保存递归过程的结构,这里想要用队列,考虑迭代中退出循环的标准(队列为空)
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
queue:=[]*TreeNode{root, root}
var r1, r2 *TreeNode
for len(queue)>0 {
r1, r2 = queue[0], queue[1]
queue=queue[2:]
if !(r1==nil && r2==nil) {
if (r1==nil)||(r2==nil) {
return false
}
if r1.Val!=r2.Val {
return false
}
queue=append(queue, r1.Left)
queue=append(queue, r2.Right)
queue=append(queue, r1.Right)
queue=append(queue, r2.Left)
}
}
return true
}
提交结果如下 :果然时间和空间只能有一个