1. 程式人生 > >【leetcode】129.(Medium)Sum Root to Leaf Numbers

【leetcode】129.(Medium)Sum Root to Leaf Numbers

解題思路:
思路一:

使用DFS,然後用一個list(記為curPath)來記錄當前路徑的所有數值,當訪問到根節點時將curPath中的數值轉換為一個整型數值,計入到結果(res)中。


提交程式碼:

class Solution {
    public int sumNumbers(TreeNode root) {
    	if(root==null)	return 0;
    	int[] res=new int[1];res[0]=0;
    	List<Integer> curPath=new ArrayList<>();
    	curPath.
add(root.val); findPath(root,curPath,res); return res[0]; } private void findPath(TreeNode root,List<Integer> curPath,int[] res) { if(root.left==null&&root.right==null) { res[0]+=addVal(curPath); return; } if(root.left!=null) { curPath.
add(root.left.val); findPath(root.left,curPath,res); curPath.remove(curPath.size()-1); } if(root.right!=null) { curPath.add(root.right.val); findPath(root.right,curPath,res); curPath.remove(curPath.size()-1); } } private int addVal(List<Integer>
list) { int res=0; for(int i=0;i<list.size();i++) res+=list.get(i)*Math.pow(10, list.size()-i-1); return res; } }

執行結果:
在這裡插入圖片描述

思路二:

上述程式碼過於複雜和費時的原因是 我企圖遍歷到葉節點時就將當前路徑的結果加入到最終結果res中 。例如對於這顆樹:

在這裡插入圖片描述
我先走到節點5,然後將這條路徑中的數值495計入到結果中,然後回到根節點9,再遍歷到葉節點1,得到數值491,再計入到最終結果res中。
如果是這種方式,我需要一個list(程式碼中用curPath表示)來維護當前的路徑值,同時需要實時地更新當前的結果——一個int型的變數res。但是一個整型的數值是不能在函式之間傳播的,所以我將res設定為一個長度為1的陣列,通過修改這個陣列的值來達到更新res的目的。

改善的方法是將左右子樹的結果傳遞到父結點,然後加上父結點的值後一層一層上傳當前層的節點值,例如對於同樣的一顆樹:
在這裡插入圖片描述
遍歷到葉節點5時,5的左右子樹為空,因此將數值5上傳給9。同時遍歷到葉節點1時,1將數值1上傳給9。此時9的左子樹數值為5,右子樹數值為1,更新為95+91=186後,節點9將自己的數值186上傳給父節點4。
這樣處理下來就不用額外的list變數來維護當前路徑中的數值了,也不用實時更新當前的結果值res。
總之就是將從上到下的計數方式改善為從下到上的計數方式

提交程式碼:

class Solution {
    public int sumNumbers(TreeNode root) {
    	return getVal(root,0);
    }
    
    private int getVal(TreeNode root,int curVal) {
        if(root==null)   return 0;
    	if(root.left==null&&root.right==null)	return curVal*10+root.val;
    	int leftVal=root.left!=null?getVal(root.left,curVal*10+root.val):0;
    	int rightVal=root.right!=null?getVal(root.right,curVal*10+root.val):0;
    	return leftVal+rightVal;
    }
}

執行結果:
在這裡插入圖片描述