0
点赞
收藏
分享

微信扫一扫

代码随想录——二叉树(二):对称,平衡,遍历路径

是她丫 2022-03-19 阅读 42

题目来自:https://www.programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%A7%8D%E7%B1%BB

文章目录

1. 对称二叉树

101. 对称二叉树

  1. 递归
  2. 迭代
	/*
	 * 1.递归法
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:39.5 MB, 在所有 Java 提交中击败了38.81%的用户
	 */
	public boolean isSymmetric1(TreeNode root) {
		return compare(root.left , root.right);
	}
		
	private boolean compare(TreeNode left, TreeNode right) {
		/* 1.左右都空,true
		 * 2.左右一个空,flase
		 * 3.左右不等,flase
		 * 4.内侧递归
		 * 5.外侧递归
		 */
		if( left == null && right == null ) return true;
		if( left != null && right == null ) return false;
		if( left == null && right != null ) return false;
		if( left.val != right.val ) return false;
			
		boolean l = compare(left.left, right.right);
		boolean r = compare(left.right, right.left);
		
		return l && r;
	}
	
	/**
     * 迭代法使用普通队列
     * 执行用时:1 ms, 在所有 Java 提交中击败了23.01%的用户
     * 内存消耗:39.4 MB, 在所有 Java 提交中击败了50.90%的用户
     */
    public boolean isSymmetric3(TreeNode root) {
        Queue<TreeNode> deque = new LinkedList<>();
        deque.offer(root.left);
        deque.offer(root.right);
        while (!deque.isEmpty()) {
            TreeNode leftNode = deque.poll();
            TreeNode rightNode = deque.poll();
            if (leftNode == null && rightNode == null) {
                continue;
            }
//            if (leftNode == null && rightNode != null) {
//                return false;
//            }
//            if (leftNode != null && rightNode == null) {
//                return false;
//            }
//            if (leftNode.val != rightNode.val) {
//                return false;
//            }
            // 以上三个判断条件合并
            if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
                return false;
            }
            // 这里顺序与使用Deque不同
            deque.offer(leftNode.left);
            deque.offer(rightNode.right);
            deque.offer(leftNode.right);
            deque.offer(rightNode.left);
        }
        return true;
    }

100. 相同的树

跟上面那题做法一样

	/*
	 * 1. 迭代法
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38.8 MB, 在所有 Java 提交中击败了34.52%的用户
	 */
	public boolean isSameTree1(TreeNode p, TreeNode q) {
		if( p == null && q == null) return true;
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(p);
		queue.offer(q);
		while(!queue.isEmpty()){

			TreeNode n1 = queue.poll();
			TreeNode n2 = queue.poll();
			if(n1 == null && n2 == null) continue;
			if(n1 == null || n2 == null || n1.val != n2.val) return false;
			//System.out.println("n1:" + n1.val + ", n2:" + n2.val);
			
			queue.offer(n1.left);
			queue.offer(n2.left);
			queue.offer(n1.right);
			queue.offer(n2.right);
		}		
		return true;
	}

	/*
	 * 递归法
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38.8 MB, 在所有 Java 提交中击败了32.54%的用户
	 */
	public boolean isSameTree(TreeNode p, TreeNode q) {
		return isSame(p, q);
	}
	public boolean isSame(TreeNode p, TreeNode q){
		if(p == null && q == null) return true;
		if(p == null || q == null || p.val != q.val) return false;
		
		boolean isl = isSame(p.left, q.left);
		boolean isr = isSame(p.right, q.right);
		
		return isl && isr;
	}

572. 另一棵树的子树

这题下线很低,上限很高

  1. 遍历每一个结点,每一个结点判断是否相等
  2. kmp算法
  3. 构造哈希,埃氏筛。不是给人做的

2. 平衡二叉树

110. 平衡二叉树

https://leetcode-cn.com/problems/balanced-binary-tree/

  1. 递归(如果不平衡就是-1)
  2. 迭代,没写
    public boolean isBalanced(TreeNode root) {
		return geth(root) != -1;
	}
	
	public int geth(TreeNode root) {
		if(root == null) return 0;
		int l = geth(root.left);
		if(l == -1) return -1;
		int r = geth(root.right);
		if(r == -1) return -1;
		if(Math.abs(l-r) > 1) return -1;		
		return Math.max(l, r) + 1;		
	}

3. 二叉树路径

257. 二叉树的所有路径

https://leetcode-cn.com/problems/binary-tree-paths/

	/* 1.迭代法
	 * 执行用时:17 ms, 在所有 Java 提交中击败了8.78%的用户
	 * 内存消耗:41.7 MB, 在所有 Java 提交中击败了18.41%的用户
	 */	
	public List<String> binaryTreePaths(TreeNode root) {
        List<String> result = new ArrayList<>();
        if (root == null)
            return result;
        Stack<Object> stack = new Stack<>();
        // 节点和路径同时入栈
        stack.push(root);
        stack.push(root.val + "");
        while (!stack.isEmpty()) {
            // 节点和路径同时出栈
        	System.out.println(stack.toString());
            String path = (String) stack.pop();
            System.out.println(path);
            TreeNode node = (TreeNode) stack.pop();
            // 若找到叶子节点
            if (node.left == null && node.right == null) {
                result.add(path);
            }
            //右子节点不为空
            if (node.right != null) {
                stack.push(node.right);
                stack.push(path + "->" + node.right.val);
            }
            //左子节点不为空
            if (node.left != null) {
                stack.push(node.left);
                stack.push(path + "->" + node.left.val);
            }
        }
        return result;
    }
	
	
	/*
	 * 2.递归法
	 * 执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:41.8 MB, 在所有 Java 提交中击败了9.35%的用户
	 */
	public List<String> binaryTreePaths1(TreeNode root) {
		List<String> res = new ArrayList<>();
        if (root == null) return res;
        List<Integer> paths = new ArrayList<>();
        traversal(root, paths, res);
        return res;
	}
		
	private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
		paths.add(root.val);
		if(root.left == null && root.right == null){//碰到叶子结点
			StringBuilder sb = new StringBuilder();
			for(int i=0; i<paths.size()-1; i++) {
				sb.append(paths.get(i)).append("->");
			}
			sb.append(paths.get(paths.size()-1));
			res.add(sb.toString());
			return;			
		}
		if(root.left != null){
			traversal(root.left, paths, res);
			paths.remove(paths.size()-1); //回溯
		}
		if(root.right != null){
			traversal(root.right, paths, res);
			paths.remove(paths.size()-1); //回溯
		}
	}
举报

相关推荐

0 条评论