| 01 看題和準(zhǔn)備今天介紹的是LeetCode算法題中Easy級別的第145題(順位題號是637)。給定一個非空二叉樹,以數(shù)組的形式返回每一層節(jié)點(diǎn)值之和的平均值。例如:     3
   /   9  20
     /     15  7
 輸出:[3,14.5,11] 說明:第一層上的節(jié)點(diǎn)的平均值為3,第二層上的節(jié)點(diǎn)的平均值為14.5,第三層上的節(jié)點(diǎn)的平均值為11.因此返回[3,14.5,11]。 注意:節(jié)點(diǎn)值的范圍在32位有符號整數(shù)的范圍內(nèi)。 本次解題使用的開發(fā)工具是eclipse,jdk使用的版本是1.8,環(huán)境是win7 64位系統(tǒng),使用Java語言編寫和測試。
 
 02 第一種解法使用廣度優(yōu)先算法(BFS)。使用隊(duì)列來實(shí)現(xiàn),在遍歷節(jié)點(diǎn)的時候,使用了兩層循環(huán),外層控制層數(shù),內(nèi)層計(jì)算每一層的節(jié)點(diǎn)值之和,出了內(nèi)層循環(huán)后,在外層循環(huán)里計(jì)算平均值,將平均值添加進(jìn)數(shù)組中。其中有一點(diǎn)需要注意,計(jì)算節(jié)點(diǎn)值之和時,需要使用long類型,避免溢出。 /**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> list = new ArrayList<Double>();
        if (root == null) {
            return list;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            // 控制層數(shù),其大小就是當(dāng)前層數(shù)中包含的節(jié)點(diǎn)個數(shù)            
            int size = queue.size();
            int count = 0;
            // 使用long類型,避免溢出            
            long sum = 0;
            // 處理每一層的節(jié)點(diǎn)值
            while (size > 0) {
                TreeNode temp = queue.poll();
                count  ;
                if (temp != null) {
                    sum  = temp.val;
                }
                if (temp != null && temp.left != null) {
                    queue.offer(temp.left);
                }
                if (temp != null && temp.right != null) {
                    queue.offer(temp.right);
                }
                size--;
            }
            // 計(jì)算平均值,添加進(jìn)數(shù)組
            list.add(sum*1.0d/count);
        }
        return list;
    }
}
 03 第二種解法使用深度優(yōu)先算法(DFS)。在使用深度優(yōu)先算法時,需要先將每一層的節(jié)點(diǎn)值之和單獨(dú)算出來,同時還要存儲每一層的節(jié)點(diǎn)個數(shù),借助遞歸算法實(shí)現(xiàn),在得到兩組數(shù)據(jù)后,再使用一次循環(huán),計(jì)算每一層的平均值。 /**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        // 存放每一層的節(jié)點(diǎn)值總和
        List<Double> list = new ArrayList<Double>();
        if (root == null) {
            return list;
        }
        // 存放每層節(jié)點(diǎn)個數(shù)
        List<Integer> count = new ArrayList<Integer>();
        dfs(0, root, list, count);
        // 計(jì)算平均值
        for (int i=0; i<list.size(); i  ) {
            list.set(i, list.get(i)/count.get(i));
        }
        return list;
    }
    public void dfs(int deep, TreeNode root, List<Double> list, List<Integer> count) {
        if (root == null) {
            return ;
        }
        // 判斷是否還在當(dāng)前此層內(nèi)
        if (deep < list.size()) {
            list.set(deep, list.get(deep) root.val);
            count.set(deep, count.get(deep) 1);
        } else {
            // 新的一層
            list.add(1.0*root.val);
            count.add(1);
        }
        // 遞歸調(diào)用剩下的節(jié)點(diǎn)
        dfs(deep 1, root.left, list, count);
        dfs(deep 1, root.right, list, count);
    }
}
 04 小結(jié)此題本質(zhì)上是對二叉樹的BFS、DFS算法的考察,在普通遍歷節(jié)點(diǎn)的基礎(chǔ)上,分層處理節(jié)點(diǎn)數(shù)據(jù)。 算法專題目前已日更超過四個月,算法題文章145 篇,公眾號對話框回復(fù)【數(shù)據(jù)結(jié)構(gòu)與算法】、【算法】、【數(shù)據(jù)結(jié)構(gòu)】中的任一關(guān)鍵詞,獲取系列文章合集。 來源:http://www./content-1-140151.html
 |