1. 程式人生 > >LeetCode之二叉樹按層從下往上遍歷

LeetCode之二叉樹按層從下往上遍歷

題目描述:

/** 
 * Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
 *
 * For example:
 * Given binary tree {3,9,20,#,#,15,7},
 *    3
 *   / \
 *  9  20
 *  /   \
 * 15    7
 * return its bottom-up level order traversal as
: * [ * [15,7] * [9,20], * [3], * ] * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. * */

就是把二叉樹從最下層開是輸出,一層一層地向上輸出。這樣就需要每一層都會存到一個數組裡,有n層,那麼對於整個二叉樹來說,需要宣告一個二維的陣列才能滿足條件。即可以這樣宣告,ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();


最後的結果應該是這樣子的:[[15, 7],[9, 20],[3]],每一項都是一層。具體程式碼如下:

public static ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root){
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
        if(root==null)
            return ret;
        ArrayList<Integer>level = new
ArrayList<Integer>(); Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); int currentLevel=1;//遍歷的這一層的節點個數 int nextLevel=0;//遍歷的下一層的孩子節點個數 while(!queue.isEmpty()){ TreeNode node=queue.remove();//把要遍歷的節點彈出佇列 level.add(node.val);//leve儲存的是這一層的節點 currentLevel--;//每儲存一個節點,currentLevel就會少一個 if(node.left!=null){//儲存節點的左孩子節點,在這裡其實這個節點的兄弟節點已經儲存到佇列裡面去了 queue.add(node.left); nextLevel++;//記錄下一層的節點個數 } if(node.right!=null)//儲存節點的右孩子節點,也相當於儲存下一層節點的兄弟節點 { queue.add(node.right); nextLevel++; } if(currentLevel==0){//如果這一層的節點都儲存到level中去了,那麼就把level這個陣列加入到二維陣列。 ret.add(level); level=new ArrayList<Integer>(); currentLevel=nextLevel;//下一層要遍歷的節點個數賦值給currentLevel nextLevel=0;//下下層的節點個數初始化為0 } } int i = 0, j = ret.size() - 1; while (i < j) {//把得到的二維陣列逆置 ArrayList<Integer> tmp = ret.get(i); ret.set(i, ret.get(j)); ret.set(j, tmp); i++; j--; } return ret; } //測試程式碼 public static void main(String arg[]) { TreeNode r1 = new TreeNode(3); TreeNode r2 = new TreeNode(9); TreeNode r3 = new TreeNode(20); TreeNode r4 = new TreeNode(15); TreeNode r5 = new TreeNode(7); r1.left = r2; r1.right = r3; r2.left=r4; r3.right=r5; ArrayList<ArrayList<Integer>> array=levelOrderBottom(r1); for(int i=0;i<array.size();i++) { System.out.print(array.get(i)+","); } }

遍歷的思想是,每遍歷一層就把這一層的資料儲存到二維數組裡,最後把得到的二維數組裡的每一項逆置一下就是從下往上遍歷的結果了。程式碼中currentLevel記錄的就是這一層的資料,每次當currentLevel為0時,說明這一層的陣列已經遍歷完了,然後存進二維數組裡。nextLevel記錄的是下一層節點的個數,在這一層遍歷完之後,會把nextLevel的值賦給currentLevel。所以每次往佇列queue中儲存一個節點currentLevel的值就會減一(currentLevel–)。level陣列儲存的就是遍歷的這一層的資料。每次要遍歷的節點都會提前儲存到queue隊列當中,使用queue的好處就是先進先出,先儲存的優先遍歷,這樣就能保證每次在把第(n+1)層孩子節點儲存到queue中時,還能讓第(n)層的兄弟節點優先彈出來。