秋招冲刺计划(Day12)
路径总和III:
437. 路径总和 III - 力扣(LeetCode)
题目:
给定一个二叉树的根节点
root
,和一个整数targetSum
,求该二叉树里节点值之和等于targetSum
的 路径 的数目。路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8 输出:3 解释:和等于 8 的路径有 3 条,如图所示。示例 2:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:3提示:
- 二叉树的节点个数的范围是
[0,1000]
-109 <= Node.val <= 109
-1000 <= targetSum <= 1000
思路:
代码:
class Solution {public int pathSum(TreeNode root, long targetSum) {if(root == null) return 0;int ret = findTarget(root,targetSum);ret+=pathSum(root.left,targetSum);ret+=pathSum(root.right,targetSum);return ret;}private int temp;public int findTarget(TreeNode root,long targetSum) {temp=0;if(root == null) return 0;if(root.val == targetSum) temp++;temp+=findTarget(root.left,targetSum-root.val);temp+=findTarget(root.right,targetSum-root.val);return temp;}
}
二叉树的最近公共祖先:
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
题目:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出:3 解释:节点5
和节点1
的最近公共祖先是节点3 。
示例 2:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点5
和节点4
的最近公共祖先是节点5 。
因为根据定义最近公共祖先节点可以为节点本身。示例 3:
输入:root = [1,2], p = 1, q = 2 输出:1提示:
- 树中节点数目在范围
[2, 105]
内。-109 <= Node.val <= 109
- 所有
Node.val
互不相同
。p != q
p
和q
均存在于给定的二叉树中。
思路:
首先需要注意一下刚回归条件,也是就递归停止的条件。
是root == null || root == p || root == q;
之后分为以下三种情况:
1、如果返回的p的root和q的root相等,那直接返回;证明他们的祖先是一样的
2、如果返回的p的root不为空,q的root为空,证明p和q是同一边的,只不过q是p的子集。
3、如果返回的q的root不为空,p的root为空,证明p和q是同一边的,只不过p是q的子集。
代码:
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null || root == p|| root == q) {return root;}TreeNode leftRoot = lowestCommonAncestor(root.left,p,q);TreeNode rightRoot = lowestCommonAncestor(root.right,p,q);if(leftRoot == rightRoot) return leftRoot;if(leftRoot != null && rightRoot == null) return leftRoot;if(rightRoot != null && leftRoot == null)return rightRoot;return root;}
}
二叉树中最大路径和:
124. 二叉树中的最大路径和 - 力扣(LeetCode)
题目:
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点
root
,返回其 最大路径和 。示例 1:
输入:root = [1,2,3] 输出:6 解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6示例 2:
输入:root = [-10,9,20,null,null,15,7] 输出:42 解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42
思路:
代码:
class Solution {private int ret = Integer.MIN_VALUE;public int maxPathSum(TreeNode root) {if(root == null)return 0;findMax(root);return ret;}public int findMax(TreeNode root) {if(root == null) return 0;int left = Math.max(0,findMax(root.left));int right = Math.max(findMax(root.right),0);if(left <0 && right<0) return root.val;if(left+right+root.val > ret) ret = left+right+root.val;return root.val+Math.max(left,right);}
}
全排列:
46. 全排列 - 力扣(LeetCode)
题目:
给定一个不含重复数字的数组
nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。示例 1:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2:
输入:nums = [0,1] 输出:[[0,1],[1,0]]示例 3:
输入:nums = [1] 输出:[[1]]提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums
中的所有整数 互不相同
思路:
代码:
class Solution {public List<List<Integer>> permute(int[] nums) {List<List<Integer>> ret = new ArrayList<>();List<Integer> path = new ArrayList<>();int len = nums.length;//记录遍历过的数据boolean[] used = new boolean[len];dfs(nums,len,0,path,used,ret);return ret;}public void dfs(int[] nums,int len,int depth,List<Integer> path,boolean[] used,List<List<Integer>> ret) {if(depth == len) {ret.add(new ArrayList<>(path));return;}for(int i = 0;i<len;i++) {if(!used[i]) {path.add(nums[i]);used[i] = true;dfs(nums,len,depth+1,path,used,ret);//出来的时候恢复原样used[i] = false;path.remove(path.size()-1);}}}
}