From d6b00cd3b8663b10e45cad136da48e2140d0b66d Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Fri, 23 Sep 2022 18:22:05 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/markilue/leecode/tree/HasPathSum.java | 153 +++++++++++++++++ .../com/markilue/leecode/tree/PathSum.java | 161 ++++++++++++++++++ 2 files changed, 314 insertions(+) create mode 100644 Leecode/src/main/java/com/markilue/leecode/tree/HasPathSum.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/tree/PathSum.java diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/HasPathSum.java b/Leecode/src/main/java/com/markilue/leecode/tree/HasPathSum.java new file mode 100644 index 0000000..937151e --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/HasPathSum.java @@ -0,0 +1,153 @@ +package com.markilue.leecode.tree; + +import org.junit.Test; + +import java.util.Stack; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-09-23 16:54 + * @Description: + * TODO 力扣112题 路径总和: + * 给你二叉树的根节点root 和一个表示目标和的整数targetSum 。 + * 判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum 。 + * 如果存在,返回 true ;否则,返回 false 。 + *

+ * 叶子节点 是指没有子节点的节点。 + * @Version: 1.0 + */ +public class HasPathSum { + + @Test + public void test() { + TreeNode root = new TreeNode(5); + TreeNode TreeNode2 = new TreeNode(4); + TreeNode TreeNode3 = new TreeNode(8); + TreeNode TreeNode4 = new TreeNode(11); + TreeNode TreeNode5 = new TreeNode(13); + TreeNode TreeNode6 = new TreeNode(4); + TreeNode TreeNode7 = new TreeNode(7); + TreeNode TreeNode8 = new TreeNode(2); + TreeNode TreeNode9 = new TreeNode(1); + + root.setRight(TreeNode3); + root.setLeft(TreeNode2); + TreeNode2.setLeft(TreeNode4); + TreeNode3.setLeft(TreeNode5); + TreeNode3.setRight(TreeNode6); + TreeNode4.setLeft(TreeNode7); + TreeNode4.setRight(TreeNode8); + TreeNode6.setRight(TreeNode9); + + System.out.println(hasPathSum(root, 22)); + } + + @Test + public void test1() { + TreeNode root = new TreeNode(1); + TreeNode TreeNode2 = new TreeNode(2); +// TreeNode TreeNode3 = new TreeNode(8); +// TreeNode TreeNode4 = new TreeNode(11); +// TreeNode TreeNode5 = new TreeNode(13); +// TreeNode TreeNode6 = new TreeNode(4); +// TreeNode TreeNode7 = new TreeNode(7); +// TreeNode TreeNode8 = new TreeNode(2); +// TreeNode TreeNode9 = new TreeNode(1); + +// root.setRight(TreeNode3); + root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode3.setLeft(TreeNode5); +// TreeNode3.setRight(TreeNode6); +// TreeNode4.setLeft(TreeNode7); +// TreeNode4.setRight(TreeNode8); +// TreeNode6.setRight(TreeNode9); + + System.out.println(hasPathSum1(root, 1)); + } + + /** + * 自己思路递归法: + * 速度击败100%,内存击败59.98% + */ + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) { + return false; + } + + return sum(root, 0, targetSum); + + } + + public boolean sum(TreeNode node, int sum, int targetSum) { + sum += node.val; + if (node.left == null && node.right == null) { + return sum == targetSum; + } + boolean left = false; + boolean right = false; + if (node.left != null) { + left = sum(node.left, sum, targetSum); + } + if (node.right != null) { + right = sum(node.right, sum, targetSum); + } + return left || right; + } + + /** + * 自己思路迭代法: + * 速度击败6.58%,内存击败54.85% + */ + public boolean hasPathSum1(TreeNode root, int targetSum) { + + if (root == null) { + return false; + } + Stack treeNodes = new Stack<>(); + Stack treeSums = new Stack<>(); + treeNodes.push(root); + treeSums.push(0); + while (!treeNodes.empty()) { + TreeNode node = treeNodes.pop(); + int sum = treeSums.pop(); + sum += node.val; + if (node.left == null && node.right == null) { + if(sum==targetSum){ + return true; + } + }else { + //注意这里不能把treeSums.push(sum);放外面,因为可能要放两次 + if(node.left!=null){ + treeNodes.push(node.left); + treeSums.push(sum); + } + if(node.right!=null){ + treeNodes.push(node.right); + treeSums.push(sum); + } + } + + } + + + return false; + + } + + /** + * 代码随想录思路递归法:极简版 + * 速度击败100%,内存击败59.98% + */ + public boolean hasPathSum2(TreeNode root, int targetSum) { + if (root == null) { + return false; + } + if(root.left==null&&root.right==null&&targetSum==0)return true; + return hasPathSum2(root.left,targetSum- root.val)||hasPathSum2(root.right,targetSum- root.val); + } + + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/PathSum.java b/Leecode/src/main/java/com/markilue/leecode/tree/PathSum.java new file mode 100644 index 0000000..f58d50a --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/PathSum.java @@ -0,0 +1,161 @@ +package com.markilue.leecode.tree; + +import org.junit.Test; + +import java.util.*; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-09-23 17:44 + * @Description: + * TODO 力扣113题 路径总和II: + * 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 + * @Version: 1.0 + */ +public class PathSum { + + + @Test + public void test(){ + TreeNode root = new TreeNode(5); + TreeNode TreeNode2 = new TreeNode(4); + TreeNode TreeNode3 = new TreeNode(8); + TreeNode TreeNode4 = new TreeNode(11); + TreeNode TreeNode5 = new TreeNode(13); + TreeNode TreeNode6 = new TreeNode(4); + TreeNode TreeNode7 = new TreeNode(7); + TreeNode TreeNode8 = new TreeNode(2); + TreeNode TreeNode9 = new TreeNode(1); + TreeNode TreeNode10 = new TreeNode(5); + + root.setRight(TreeNode3); + root.setLeft(TreeNode2); + TreeNode2.setLeft(TreeNode4); + TreeNode3.setLeft(TreeNode5); + TreeNode3.setRight(TreeNode6); + TreeNode4.setLeft(TreeNode7); + TreeNode4.setRight(TreeNode8); + TreeNode6.setRight(TreeNode9); + TreeNode6.setLeft(TreeNode10); + + System.out.println(pathSum(root, 22)); + } + + @Test + public void test1() { + TreeNode root = new TreeNode(1); + TreeNode TreeNode2 = new TreeNode(2); +// TreeNode TreeNode3 = new TreeNode(8); +// TreeNode TreeNode4 = new TreeNode(11); +// TreeNode TreeNode5 = new TreeNode(13); +// TreeNode TreeNode6 = new TreeNode(4); +// TreeNode TreeNode7 = new TreeNode(7); +// TreeNode TreeNode8 = new TreeNode(2); +// TreeNode TreeNode9 = new TreeNode(1); + +// root.setRight(TreeNode3); + root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode3.setLeft(TreeNode5); +// TreeNode3.setRight(TreeNode6); +// TreeNode4.setLeft(TreeNode7); +// TreeNode4.setRight(TreeNode8); +// TreeNode6.setRight(TreeNode9); + + System.out.println(pathSum(root, 0)); + } + + /** + * 自己思路递归法:以空间换时间 实际上是深度优先算法 + * 速度击败99.98%,内存击败30.39% + * @param root + * @param targetSum + * @return + */ + public List> pathSum(TreeNode root, int targetSum) { + if(root==null){ + return new ArrayList<>(); + } + List> result = new ArrayList<>(); + path(root,targetSum,0,new ArrayList<>(),result); + return result; + + } + + + public void path(TreeNode node,int targetSum,int sum,List list,List> result){ + sum+=node.val; + list.add(node.val); + if(node.left==null&&node.right==null&&sum==targetSum){ + //换一个list,避免修改这一个 + List result1 = new ArrayList<>(); + result1.addAll(list); + result.add(result1); + return; + } + if(node.left!=null){ + path(node.left,targetSum,sum,list,result); + list.remove(list.size()-1); + } + if(node.right!=null){ + path(node.right,targetSum,sum,list,result); + list.remove(list.size()-1); + } + + } + + + + + //官方广度优先算法:核心是通过map记录他的爹是谁,方便后续回溯 + List> ret = new LinkedList>(); + Map map = new HashMap(); + + public List> pathSum1(TreeNode root, int targetSum) { + if (root == null) { + return ret; + } + + Queue queueNode = new LinkedList(); + Queue queueSum = new LinkedList(); + queueNode.offer(root); + queueSum.offer(0); + + while (!queueNode.isEmpty()) { + TreeNode node = queueNode.poll(); + int rec = queueSum.poll() + node.val; + + if (node.left == null && node.right == null) { + if (rec == targetSum) { + getPath(node); + } + } else { + if (node.left != null) { + map.put(node.left, node); + queueNode.offer(node.left); + queueSum.offer(rec); + } + if (node.right != null) { + map.put(node.right, node); + queueNode.offer(node.right); + queueSum.offer(rec); + } + } + } + + return ret; + } + + public void getPath(TreeNode node) { + List temp = new LinkedList(); + while (node != null) { + temp.add(node.val); + node = map.get(node); + } + Collections.reverse(temp); + ret.add(new LinkedList(temp)); + } + +}