面试题07. 重建二叉树
//C/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){ if(preorderSize == 0){ return NULL; } int rootNum = preorder[0]; struct TreeNode *root; int i ; root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); root->val = rootNum; for(i = 0; i < inorderSize; i++){ if(inorder[i] == rootNum){ break; } } root->left = (i == 0) ? NULL : buildTree(preorder+1, i, inorder, i); root->right = (i == inorderSize-1) ? NULL : buildTree(preorder+1+i, preorderSize-1-i, inorder+1+i, inorderSize-1-i); return root;}```# 面试题32-I.从上到下打印二叉树![在这里插入图片描述](https://img-blog.csdnimg.cn/20200331143332949.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjA3MjI4MA==,size_16,color_FFFFFF,t_70)```java//java anan 2020.3.31class Solution { public int[] levelOrder(TreeNode root) { if(root == null) return new int[0]; //输入:[] Queue<TreeNode> queue = new LinkedList<>(); ArrayList<Integer> res = new ArrayList<>(); queue.offer(root); while(!queue.isEmpty()){ TreeNode p = queue.poll(); res.add(p.val); if(p.left != null) queue.offer(p.left); if(p.right != null) queue.offer(p.right); } return res.stream().mapToInt(Integer::intValue).toArray(); }}```# 面试题32-II.从上到下打印二叉树 (102)![在这里插入图片描述](https://img-blog.csdnimg.cn/20200331161007559.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjA3MjI4MA==,size_16,color_FFFFFF,t_70)## 安安:迭代[参考题解](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/)```java//javaclass Solution { public List<List<Integer>> levelOrder(TreeNode root) { Queue<TreeNode> queue = new LinkedList<>(); List<List<Integer>> res = new ArrayList<>(); if(root == null) return res; //输入:[] queue.offer(root); while(!queue.isEmpty()){ List<Integer> tmp = new ArrayList<Integer>(); for(int i = queue.size(); i > 0; i--){ TreeNode p = queue.poll(); tmp.add(p.val); if(p.left != null) queue.offer(p.left); if(p.right != null) queue.offer(p.right); } res.a#
```c
//C
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
if(preorderSize == 0){
return NULL;
}
int rootNum = preorder[0];
struct TreeNode *root;
int i ;
root = (struct TreeNode *)malloc(sizeof(struct TreeNode));
root->val = rootNum;
for(i = 0; i < inorderSize; i++){
if(inorder[i] == rootNum){
break;
}
}
root->left = (i == 0) ? NULL : buildTree(preorder+1, i, inorder, i);
root->right = (i == inorderSize-1) ? NULL : buildTree(preorder+1+i, preorderSize-1-i, inorder+1+i, inorderSize-1-i);
return root;
}
面试题32-I.从上到下打印二叉树
//java anan 2020.3.31
class Solution {
public int[] levelOrder(TreeNode root) {
if(root == null) return new int[0]; //输入:[]
Queue<TreeNode> queue = new LinkedList<>();
ArrayList<Integer> res = new ArrayList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode p = queue.poll();
res.add(p.val);
if(p.left != null) queue.offer(p.left);
if(p.right != null) queue.offer(p.right);
}
return res.stream().mapToInt(Integer::intValue).toArray();
}
}
面试题32-II.从上到下打印二叉树 (102)
安安:迭代
//java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res; //输入:[]
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> tmp = new ArrayList<Integer>();
for(int i = queue.size(); i > 0; i--){
TreeNode p = queue.poll();
tmp.add(p.val);
if(p.left != null) queue.offer(p.left);
if(p.right != null) queue.offer(p.right);
}
res.add(tmp);
}
return res;
}
}
官解1:迭代 O(n)
//java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> levels = new ArrayList<List<Integer>>();
if (root == null) return levels;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
int level = 0;
while ( !queue.isEmpty() ) {
// start the current level
levels.add(new ArrayList<Integer>());
// number of elements in the current level
int level_length = queue.size();
for(int i = 0; i < level_length; ++i) {
TreeNode node = queue.remove();
// fulfill the current level
levels.get(level).add(node.val);
// add child nodes of the current level
// in the queue for the next level
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
// go to next level
level++;
}
return levels;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
官解2:递归 O(n) dfs+层标记
//java class Solution {
List<List<Integer>> levels = new ArrayList<List<Integer>>();
public void helper(TreeNode node, int level) {
// start the current level
if (levels.size() == level)
levels.add(new ArrayList<Integer>());
// fulfil the current level
levels.get(level).add(node.val);
// process child nodes for the next level
if (node.left != null)
helper(node.left, level + 1);
if (node.right != null)
helper(node.right, level + 1);
}
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) return levels;
helper(root, 0);
return levels;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
面试题32-III.从上到下打印二叉树
法1:迭代
//java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()) {
List<Integer> tmp = new ArrayList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
if(res.size() % 2 == 1) Collections.reverse(tmp); //反转
res.add(tmp);
}
return res;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//java 不用反转
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()) {
List<Integer> tmp = new ArrayList<>();
for(int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
if(res.size() % 2 == 1){
tmp.add(0, node.val);
}else{
tmp.add(node.val);
}
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
res.add(tmp);
}
return res;
}
}
法2:递归
//java
//根节点认为第0层 偶数层从末尾追加 奇数层从头添加
class Solution {
List<List<Integer>> res = new ArrayList<>();
public void helper(TreeNode node, int level){
if(res.size() == level){
res.add(new ArrayList<Integer>());
}
if(level%2 == 0) res.get(level).add(node.val); //偶数
else res.get(level).add(0, node.val); //奇数
if(node.left != null) helper(node.left, level+1);
if(node.right != null) helper(node.right, level+1);
}
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null) return res;
helper(root, 0);
return res;
}
}
法3:双栈法(剑指offer)
//Java 安安 2020.3.31
//根节点作为第0行
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
Stack<TreeNode> s1 = new Stack<>(); //存储奇数行
Stack<TreeNode> s2 = new Stack<>(); //存储偶数行
if(root != null) s2.push(root);
while(!s1.empty() || !s2.empty()) {
List<Integer> tmp = new ArrayList<>();
if(!s2.empty()){
while(!s2.empty()){
TreeNode p = s2.pop();
tmp.add(p.val);
if(p.left != null) s1.push(p.left);
if(p.right != null) s1.push(p.right);
}
res.add(tmp);
}
if(!s1.empty()){
tmp = new ArrayList<>();
while(!s1.empty()){
TreeNode p = s1.pop();
tmp.add(p.val);
if(p.right != null) s2.push(p.right);
if(p.left != null) s2.push(p.left);
}
res.add(tmp);
}
}
return res;
}
}
面试题26.树的子结构
版本1
//java anan 2020.4.3
class Solution {
TreeNode A1;
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A == null || B == null) return false;
boolean flag1 = inOrderTraverse(A, B);
boolean flag2 = false;;
if(flag1){
flag2 = inOrderTraverseTwoTrees(A1, B);
}
System.out.println(flag1 + " " + flag2);
return flag1&&flag2;
}
public boolean inOrderTraverse(TreeNode A, TreeNode B){
if(A != null && B != null){
if(A.val != B.val){
return inOrderTraverse(A.left, B) || inOrderTraverse(A.right, B);
}else{
A1 = A;
return true;
}
}else{
return false;
}
}
public boolean inOrderTraverseTwoTrees(TreeNode A, TreeNode B){
if(B != null && A != null){
if(A.val == B.val){
if(B.left == null) return inOrderTraverseTwoTrees(A.right, B.right);
else if(B.right == null) return inOrderTraverseTwoTrees(A.left, B.left);
else return inOrderTraverseTwoTrees(A.left, B.left) && inOrderTraverseTwoTrees(A.right, B.right);
}else{
return false;
}
}else if(B == null){
return true;
}
return false;
}
}
版本2
//java 对上一个版本的代码进行了优化 但还是无法判断第一个值相同的节点,只能判断一个
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return hasSameValueNode(A,B);
}
public boolean hasSameValueNode(TreeNode A, TreeNode B){ //判断A中有没有和B根节点值相同的节点
if(A == null || B == null) return false;
if(A.val != B.val){
return hasSameValueNode(A.left, B) || hasSameValueNode(A.right, B);
}else{
return isPartSame(A, B);
}
}
public boolean isPartSame(TreeNode A, TreeNode B){ //从两个树的根节点开始遍历这两个树,看是否有相同的部分
if(B == null) return true;
if(A == null) return false;
if(A.val == B.val){
return isPartSame(A.left, B.left) && isPartSame(A.right, B.right);
}else{
return false;
}
}
}
版本3
//java
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(B==null||A==null) return false;
if(!isSub(A,B)) //放到这个地方调用第二个函数,就可以判断除第一个相同值的节点外的其余相同值的节点
return isSubStructure(A.left,B) || isSubStructure(A.right,B);
return true;
}
public boolean isPartSame(TreeNode A, TreeNode B) {
if(B==null) return true;
if(A==null) return false;
if(A.val==B.val)
return isPartSame(A.left,B.left) && isPartSame(A.right,B.right);
else
return false;
}
}
作者:orangex
链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/tao-wa-ta-lai-liao-jing-pin-tu-jie-by-orangex/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
版本4
//java 3的代码优化
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) return false;
return DFS(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B);
}
public boolean DFS(TreeNode A, TreeNode B) {
if (B == null) return true;
if (A == null) return false;
return A.val == B.val && DFS(A.left,B.left) && DFS(A.right,B.right);
}
}
作者:le-ge-zhi-shang
链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/100ji-bai-di-gui-shen-du-you-xian-sou-suo-by-le-ge/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
面试题27.二叉树的镜像(226)
安安题解:递归 新建了一棵树
//java 安安 2020.4.3
//安安思路;又新建了一棵树,遍历原树时,将原树左右子树的值交换作为新树左右子树节点的值
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return root;
TreeNode mroot = new TreeNode(root.val);
inOrderTraverse(root, mroot);
return mroot;
}
public void inOrderTraverse(TreeNode root, TreeNode mroot){
if(root != null){
mroot.val = root.val;
if(root.left != null){
mroot.right = new TreeNode(root.left.val);
}
if(root.right != null){
mroot.left = new TreeNode(root.right.val);
}
inOrderTraverse(root.left, mroot.right);
inOrderTraverse(root.right, mroot.left);
}
}
}
解1:递归 所谓的“ 一看就会 一写就废”系列
//java
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
TreeNode tmp = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(tmp);
return root;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解2:辅助栈(或队列)
//java 辅助栈
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>() {{ add(root); }};
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if(node.left != null) stack.add(node.left);
if(node.right != null) stack.add(node.right);
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
return root;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//java 辅助队列
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll();
TreeNode temp = current.left;
current.left = current.right;
current.right = temp;
if (current.left != null) queue.add(current.left);
if (current.right != null) queue.add(current.right);
}
return root;
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/invert-binary-tree/solution/fan-zhuan-er-cha-shu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
面试题28.对称的二叉树(101)
递归法:版本1
//java anan 2020.4.3
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true; //[]
return isSymmetricOfTwoTrees(root.left, root.right);
}
public boolean isSymmetricOfTwoTrees(TreeNode left, TreeNode right){
if(left != null && right != null){
if(left.val == right.val){
return isSymmetricOfTwoTrees(left.left, right.right) && isSymmetricOfTwoTrees(left.right, right.left);
}else{
return false;
}
}else if(left == null && right == null){
return true;
}else{
return false;
}
}
}
递归法:版本2
//java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true; //[]
return isSymmetricOfTwoTrees(root.left, root.right);
}
public boolean isSymmetricOfTwoTrees(TreeNode left, TreeNode right){
if(left == null && right == null) return true;
if(left == null || right == null) return false;
if(left.val == right.val){
return isSymmetricOfTwoTrees(left.left, right.right) && isSymmetricOfTwoTrees(left.right, right.left);
}else{
return false;
}
}
}
递归法:版本3
//java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true; //[]
return isSymmetricOfTwoTrees(root.left, root.right);
}
public boolean isSymmetricOfTwoTrees(TreeNode left, TreeNode right){
if(left == null && right == null) return true;
if(left == null || right == null) return false;
return left.val == right.val && isSymmetricOfTwoTrees(left.left, right.right) && isSymmetricOfTwoTrees(left.right, right.left);
}
}
递归法:别人家的
//java
public boolean isSymmetric(TreeNode root) {
return isMirror(root, root);
}
public boolean isMirror(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null) return false;
return (t1.val == t2.val)
&& isMirror(t1.right, t2.left)
&& isMirror(t1.left, t2.right);
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
迭代法:错误版本
//java 本来想着 空的不加进去了 结果过不了
//[1,2,2,null,3,null,3] 这个案例不能通过
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true; //[]
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
queue.add(root);
while(!queue.isEmpty()){
TreeNode q1 = queue.poll();
TreeNode q2 = queue.poll();
if(q1.val != q2.val) return false;
if(q1.left != null) queue.add(q1.left);
if(q2.right != null) queue.add(q2.right);
if(q1.right != null) queue.add(q1.right);
if(q2.left != null) queue.add(q2.left);
}
return true;
}
}
迭代法:正确版本
//java 正确版本
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
q.add(root);
while (!q.isEmpty()) {
TreeNode t1 = q.poll();
TreeNode t2 = q.poll();
if (t1 == null && t2 == null) continue;
if (t1 == null || t2 == null) return false;
if (t1.val != t2.val) return false;
q.add(t1.left);
q.add(t2.right);
q.add(t1.right);
q.add(t2.left);
}
return true;
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
面试题33.二叉搜索树的后序遍历序列
安安
//java 2020.4.6 anan 看了思路自己写的
class Solution {
public boolean verifyPostorder(int[] postorder) {
if(postorder.length == 1 || postorder.length == 0) return true; //特殊输入:[]
int rootVal = postorder[postorder.length-1];
int index = -1; //划分左右子树的下标 右子树第一个节点的下标
//找划分左右子树的下标
for(int i=0; i < postorder.length-1; i++){
if(postorder[i] > rootVal){
index = i;
break;
}
}
//找到这个划分下标以后 从这个下标之后遍历的值都比根节点要大
//若没有找到这个下标,说明最后一个值前面的值都比root的值要小
if(index != -1){
for(int i = index; i < postorder.length-1; i++){
if(postorder[i] < rootVal) return false;
}
}
//index==0 表示只有右子树
//index==-1表示只有左子树
//另外一个表示左右子树都有
if(index == 0) return verifyPostorder(Arrays.copyOfRange(postorder, index, postorder.length-1));
else if(index == -1) return verifyPostorder(Arrays.copyOfRange(postorder, 0, postorder.length-1));
else return verifyPostorder(Arrays.copyOfRange(postorder, 0, index)) && verifyPostorder(Arrays.copyOfRange(postorder, index, postorder.length-1));
}
}
别人:一直用同一个数组,通过下标进行操作
//java
class Solution {
public boolean verifyPostorder(int [] postorder) {
if (postorder.length <= 2) return true;
return verifySeq(postorder, 0, postorder.length-1);
}
private boolean verifySeq(int[] postorder, int start, int end) {
if (start >= end) return true;
int i;
for (i = start; i < end; i++) {
if (postorder[i] > postorder[end]) break;
}
// 验证后面的是否都大于sequence[end]
for (int j = i; j < end; j++) {
if (postorder[j] < postorder[end]) return false;
}
return verifySeq(postorder, start, i-1) && verifySeq(postorder, i, end-1);
}
}
单调栈
//java
class Solution {
public boolean verifyPostorder(int[] postorder) {
// 单调栈使用,单调递增的单调栈
Deque<Integer> stack = new LinkedList<>();
// 表示上一个根节点的元素,这里可以把postorder的最后一个元素root看成无穷大节点的左孩子
int pervElem = Integer.MAX_VALUE;
// 逆向遍历,就是翻转的先序遍历
for (int i = postorder.length - 1;i>=0;i--){
// 左子树元素必须要小于递增栈被peek访问的元素,否则就不是二叉搜索树
if (postorder[i] > pervElem){
return false;
}
while (!stack.isEmpty() && postorder[i] < stack.peek()){
// 数组元素小于单调栈的元素了,表示往左子树走了,记录下上个根节点
// 找到这个左子树对应的根节点,之前右子树全部弹出,不再记录,因为不可能在往根节点的右子树走了
pervElem = stack.pop();
}
// 这个新元素入栈
stack.push(postorder[i]);
}
return true;
}
}
作者:burning-summer
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/solution/dan-diao-di-zeng-zhan-by-shi-huo-de-xia-tian/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
面试题34.二叉树中和为某一值的路径(113)
该题和自己之前做的dfs回溯合集很相似
版1
//java anan 2020.4.6
class Solution {
//List<List<Integer>> res = new List<List<Integer>>(); //new的是具体的实现类
List<List<Integer>> res;
int sum;
public List<List<Integer>> pathSum(TreeNode root, int sum) {
this.sum = sum;
res = new ArrayList<>();
if(root == null) return res; //特殊案例:[]
List<Integer> list = new ArrayList<Integer>(){};
list.add(root.val);
helper(root, list, root.val);
return res;
}
public void helper(TreeNode root, List<Integer> list, int sumPath){
//System.out.println(root.val + " " + sumPath + " " + list);
if(root.left == null && root.right == null){
if(sumPath == sum){
//res.add(list);
//若用此方式,将list直接添加进去,是将list对象添加进去了,后序list发生变化时,res里的值也会跟着发生变化
res.add(new ArrayList<>(list));
return ;
}
}
if(root.left != null){
list.add(root.left.val);
helper(root.left, list, sumPath+root.left.val);
list.remove(list.size()-1);
}
if(root.right != null){
list.add(root.right.val);
helper(root.right, list, sumPath+root.right.val);
list.remove(list.size()-1);
}
}
}
需要注意的点:
1.res.add(new ArrayList<>(list)); 要新建一个对象进行添加,不能直接添加原对象
2. List list 这个可以作为全局的,应为至始至终都只对这个对象进行操作
3. //List<List> res = new List<List>(); //new的是具体的实现类
res = new ArrayList<>();
4.自己只在树节点值不为0时才递归 这样代码会比较冗长
5.自己是从0开始加的 其实也可以考虑相减 递归一次减一些
版2
//java
class Solution {
List<List<Integer>> res;
List<Integer> list;
int sum;
public List<List<Integer>> pathSum(TreeNode root, int sum) {
this.sum = sum;
res = new ArrayList<>();
list = new ArrayList<Integer>(){};
helper(root, 0);
return res;
}
public void helper(TreeNode root, int sumPath){
if(root == null) return ;
sumPath+=root.val;
list.add(root.val);
//System.out.println(level + " " + root.val + " " + sumPath + " " + list);
if(root.left == null && root.right == null && sumPath == sum){
res.add(new ArrayList<>(list));
}
helper(root.left, sumPath);
helper(root.right, sumPath);
list.remove(list.size()-1);
}
}
版3:别人家的
class Solution {
LinkedList<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
recur(root, sum);
return res;
}
void recur(TreeNode root, int tar) {
if(root == null) return;
path.add(root.val);
tar -= root.val;
if(tar == 0 && root.left == null && root.right == null)
res.add(new LinkedList(path));
recur(root.left, tar);
recur(root.right, tar);
path.removeLast();
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/solution/mian-shi-ti-34-er-cha-shu-zhong-he-wei-mou-yi-zh-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
Node leftMax = root;
Node rightMin = root;
public Node treeToDoublyList(Node root) {
helper(root, leftMax, root);
return leftMax;
}
public void helper(Node root, Node leftMax, Node rightMin){
if(root.left == null && root.right == null){ //叶子节点
// leftMax = (root.val < leftMax.val) ? root : leftMax;
// rightMin = (root.val > rightMin.val) ? root : rightMin;
leftMax = root;
rightMin = root;
System.out.println("**leftMax.val:" + leftMax.val + " root.val:" + root.val);
System.out.println("**rightMin.val:" + rightMin.val + " root.val:" + root.val);
return;
}
if(root.left != null){
helper(root.left, leftMax, rightMin);
System.out.println("leftMax.val:" + leftMax.val + " root.val:" + root.val);
leftMax.right = root;
root.left = leftMax;
}
if(root.right != null){
helper(root.right, leftMax, rightMin);
System.out.println("rightMin.val:" + rightMin.val + " root.val:" + root.val);
root.right = rightMin;
rightMin.left = root;
}
}
}
面试题36.二叉搜索树和双向链表(426)
版本1
//这个同学的版本比我自己写的那个简洁许多,但是这个新建了一个节点
class Solution {
Node pre = new Node(0), head = pre;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
dfs(root);
head = head.right;
head.left = pre;
pre.right = head;
return head;
}
void dfs(Node cur) {
if(cur == null) return;
dfs(cur.left);
pre.right = cur;
cur.left = pre;
pre = cur;
dfs(cur.right);
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/mian-shi-ti-36-er-cha-sou-suo-shu-yu-shuang-xian-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
版本2
class Solution {
Node head=null,pre=null,tail=null;
public Node treeToDoublyList(Node root) {
if(root==null) return root;
//中序遍历访问节点并连接
inorder(root);
//连接头尾节点
head.left=tail;
tail.right=head;
return head;
}
private void inorder(Node root){
//递归出口
if(root==null) return ;
//访问左子树
inorder(root.left);
//将当前节点和上一个节点连接
if(pre==null) head=root;
else pre.right=root;
root.left=pre;
pre=root;
tail=root;
//访问右子树
inorder(root.right);
return ;
}
}
作者:chenjunboBUPT
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/zhong-xu-bian-li-fang-wen-jie-dian-quan-ju-bian-li/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//java 没有新建节点,都是在原节点上进行操作
//参考上述题解 进行了部分更改
class Solution {
Node pre;
Node head;
public Node treeToDoublyList(Node root) {
if(root == null) return root;
helper(root); //遍历结束后,pre是最后一个节点
head.left = pre;
pre.right = head;
return head;
}
public void helper(Node root){
if(root == null) return;
helper(root.left);
if(pre == null){
pre = root;
head = root;
}else{
pre.right = root;
root.left = pre;
pre = root;
}
helper(root.right);
}
}