手撕算法——二叉樹面試題目彙總

二叉樹遍歷

先序遍歷

遞歸

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        if(root==null){
            return list;
        }
        helper(list,root);
        return list;
    }

    public void helper(List<Integer> list,TreeNode root){
        if(root==null){
            return;
        }
        list.add(root.val);
        helper(list,root.left);
        helper(list,root.right);
    }
}

迭代

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        if(root==null){
            return list;
        }

        Stack<TreeNode> stack=new Stack<>();
        while(root!=null||!stack.isEmpty()){
            if(root!=null){
                list.add(root.val);
                stack.push(root);
                root=root.left;
            }else{
                root=stack.pop();
                root=root.right;
            }
        }
        return list;
    }
}

樹的子結構

實質上也是考察的二叉樹的遍歷
主要分爲兩步:
第一步:
遍歷二叉樹找A與B

class Solution{
	public boolean isSubStructure(TreeNode A,TreeNode B){
		boolean res=false;
        if(A!=null&&B!=null){
            if(A.val==B.val){
                res=doesTreeAhasB(A,B);
            }
            if(!res){
                res=isSubStructure(A.left,B);
            }
            if(!res){
                res=isSubStructure(A.right,B);
            }
        }

        return res;
	}
	
	boolean doesTreeAhasB(TreeNode A,TreeNode B){
		if(B==null){
            return true;
        }
        if(A==null){
            return false;
        }
        if(A.val!=B.val){
            return false;
        }

        return doesTreeAhasB(A.left,B.left)&&doesTreeAhasB(A.right,B.right);
	}
}

二叉樹中和爲某一值的路徑

面試題34.二叉樹中和爲某一值的路徑

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
       List<List<Integer> > lists=new ArrayList<>();
        //判非
        if(root==null){
            return  lists;
        }
        List<Integer> list=new ArrayList<>();
        countPathSum(root,sum,lists,list);
        return lists;
    }

    public void countPathSum(TreeNode root,int sum,List<List<Integer> > lists,List<Integer> list){
        //判斷遞歸終止條件
        if(root==null){
            return;
        }
        //當前要執行的操作
        sum-=root.val;
        list.add(root.val);
        //如果該節點爲葉子節點並且sum爲0,則加入路徑
        if(sum==0&&root.left==null&&root.right==null){
            lists.add(new ArrayList(list));
        }

        //更深層次的遍歷
        countPathSum(root.left,sum,lists,list);
        countPathSum(root.right,sum,lists,list);

        //重置
        sum+=root.val;
        list.remove(list.size()-1);

    }
}

124. 二叉樹中的最大路徑和

二叉樹中最大路徑和

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private int max=Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        if(root==null){
            return 0;
        }
        
        maxPath(root);
        return max;
    }
    public int maxPath(TreeNode node){
        if(node==null){
            return 0;
        }

        int leftmax=Math.max(maxPath(node.left),0);//如果是負值  則貢獻值置爲0
        int rightmax=Math.max(maxPath(node.right),0);

        max=Math.max(max,leftmax+rightmax+node.val);

        return node.val+Math.max(leftmax,rightmax); //只能有一邊可以參與到路徑
    }
}

二叉樹節點之間的最大距離問題

二叉樹節點間的最大距離問題
題目描述:
從二叉樹的節點 A 出發,可以向上或者向下走,但沿途的節點只能經過一次,當到達節點 B 時,路徑上的節點數叫作 A 到 B 的距離。
現在給出一棵二叉樹,求整棵樹上每對節點之間的最大距離。
輸入描述:

第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。
以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子爲 lch,右兒子爲 rch。(如果 lch 爲 0 則表示 fa 沒有左兒子,rch同理)
最後一行爲節點 o1 和 o2。

輸出描述:

輸出一個整數表示答案。

示例1:
輸入

7 1
1 2 3
2 4 5
4 0 0
5 0 0
3 6 7
6 0 0
7 0 0

輸出

5

分析以某個節點爲根節點的最大距離爲左子樹的最大高度+右子樹的最大高度+1,不斷遞歸,更新最大值。

import java.util.*;
public class Main{
    public static int res=0;
    public static void main(String[] args){
        Scanner scanner=new Scanner(System.in);
        int number=scanner.nextInt();
        int root=scanner.nextInt();
        int arr[][]=new int[number+1][2];
        for(int i=1;i<=number;i++){
            int p=scanner.nextInt();
            arr[p][0]=scanner.nextInt();
            arr[p][1]=scanner.nextInt();
        }
        
        countLevel(arr,root);
        System.out.println(res);

    }
    public static  int countLevel(int[][] arr,int node){
        if(node==0){
            return 0;
        }
        if(arr[node][0]==0&&arr[node][1]==0){
            return 1;
        }
        
        int left = countLevel(arr,arr[node][0]);
        int right = countLevel(arr,arr[node][1]);
        int path=left+right+1;
        res=Math.max(res,path);
        
        return 1+Math.max(left,right);
    }
    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章