diff --git a/scala-leetcode/src/main/scala/io/github/dreamylost/Leetcode_337_Tree.scala b/scala-leetcode/src/main/scala/io/github/dreamylost/Leetcode_337_Tree.scala index ec4ad6c4bcfe9ad81f563d3a442268ce4e6335d6..82110fd8ecef251c57cd3ac0609aba1dafd57d7e 100644 --- a/scala-leetcode/src/main/scala/io/github/dreamylost/Leetcode_337_Tree.scala +++ b/scala-leetcode/src/main/scala/io/github/dreamylost/Leetcode_337_Tree.scala @@ -18,15 +18,69 @@ package io.github.dreamylost * @time 2018年8月10日 * @version v1.0 */ -object Leetcode_337_Tree extends App { +object Leetcode_337_Tree { + /** + * 对于一个以 root 为根节点的二叉树而言,如果尝试偷取 root 节点,那么势必不能偷取其左右子节点,然后继续尝试偷取其左右子节点的左右子节点。 + * 如果不偷取该节点,那么只能尝试偷取其左右子节点比较两种方式的结果,谁大取谁。 + * + * 3768 ms,8.33% + * fold 4848ms + * 54.9 MB,100.00% + * + * @param root + * @return + */ def rob(root: TreeNode): Int = { + if (root == null) return 0 + val memory = new scala.collection.mutable.HashMap[TreeNode, Int]() + if (memory.contains(root)) return memory(root) + var ccVal = root.value + if (root.left != null) ccVal += rob(root.left.left) + rob(root.left.right) + if (root.right != null) ccVal += rob(root.right.left) + rob(root.right.right) + val cVal = rob(root.left) + rob(root.right) + memory.put(root, ccVal) + math.max(cVal, ccVal) + } + + /** + * 解决重复子问题,竟然还慢 + * + * 1372 ms,33.33% + * 52.2 MB,100.00% + * + * @param root + * @return + */ + def rob_(root: TreeNode): Int = { if (root == null) return 0 var vart = root.value - if (root.left != null) vart += rob(root.left.left) + rob(root.right.right) - if (root.right != null) vart += rob(root.right.right) + rob(root.right.right) - var valt = rob(root.left) + rob(root.right) + if (root.left != null) vart += rob(root.left.left) + rob(root.left.right) + if (root.right != null) vart += rob(root.right.left) + rob(root.right.right) + val valt = rob(root.left) + rob(root.right) math.max(valt, vart) } + /** + * 后续中递归 + * + * 688 ms,100.00% + * 53.1 MB,100.00% + * + * @param root + * @return + */ + def rob2(root: TreeNode): Int = { + if (root == null) return 0 + def helper(r: TreeNode): Seq[Int] = { + if (r == null) return Seq(0, 0) + // index 0 存储 下下层,偷root和root的下下层节点 + // index 1 存储下层(即不偷当前子树的root,而是偷root的左右子节点) + val left = helper(r.left) + val right = helper(r.right) + val h = math.max(left.head + right.head + r.value, left(1) + right(1)) + Seq(left(1) + right(1), h) + } + helper(root)(1) + } } diff --git a/scala-leetcode/src/main/scala/io/github/dreamylost/dreamylost.md b/scala-leetcode/src/main/scala/io/github/dreamylost/dreamylost.md index d66e7a8da2f71abf01bb9024a5cd44da713ba222..e3500c018216ac1ebe44fcae51273a618f24b061 100644 --- a/scala-leetcode/src/main/scala/io/github/dreamylost/dreamylost.md +++ b/scala-leetcode/src/main/scala/io/github/dreamylost/dreamylost.md @@ -17,7 +17,7 @@ * [统计左叶子节点的和](./Leetcode_404_Tree.scala) * [最小路径](./Leetcode_111_Tree.scala) * [判断路径和是否等于一个数](./Leetcode_112_Tree.scala) -* [间隔遍历](./Leetcode_337_Tree.scala) +* [间隔遍历/打家劫舍 III](./Leetcode_337_Tree.scala) * [两节点的最长路径](./Leetcode_543_Tree.scala) * [路径总和 III](./Leetcode_437_Tree.scala) * [二叉搜索树中的众数](./Leetcode_501.scala)