自己的方法:每层的值存在对应的list中,最后比较每层是不是对称。这种做法除了遍历完二叉树,还有判断list的时间,当时就觉得肯定是笨方法,但是没有观察出规律。
List<List<Integer>> list = new ArrayList<>(); public boolean isSymmetric(TreeNode root) { helper(root,0); for (List<Integer> cur : list) { int sta = 0, end = cur.size() - 1; while (sta<end) { if (cur.get(sta)!=cur.get(end)) return false; sta++; end--; } } return true; } public void helper(TreeNode root,int cur) { if (list.size()==cur) list.add(new ArrayList<>()); List<Integer> temp = list.get(cur); if (root==null) { temp.add(null); return; } temp.add(root.val); helper(root.left,cur+1); helper(root.right,cur+1); }
接下来是看的耗时短的解,通过观察和归纳可以总结出:当前对称的两个节点lt和rt,如果lt.left和rt.right,lt.right和rt.left这两对也对称的话,下一层也对称
这就不需要记录节点,直接递归判断就行
public boolean isSymmetric(TreeNode root) { return root == null || isSymmetric(root.left, root.right); } private boolean isSymmetric(TreeNode left, TreeNode right) { int nu = (left == null ? 1 : 0) + (right == null ? 1 : 0); if (nu == 1) return false; if (nu == 2) return true; return left.val == right.val && isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left); }
之前写递归函数的时候,总是在返回值类型上纠结,不知道返回一个值好还是void好。现在比较这两种做法就可以发现:
如果递归函数每层递归都可以单独的完成任务,那就不需要返回值
如果递归函数一层任务的实现需要借助下一层的结果才能完成,那就需要返回值
考虑递归的时候有点像动态规划的感觉,需要考虑的问题是,把问题一般化,考虑一般问题(部分问题)的解决方案,然后每层的方案都一样,不同的只是参数。
同样,一个任务如果可以分解为解决方法相同,只是参数不同的几个小问题,那么就可以用递归