Post-order Traversal: stack/recursive/morris

[廣告]分治/遞歸 思想總結(jié):http://www.reibang.com/p/6c1de969830c

  1. Symmetric Tree
    [post-order]Recursive check
class Solution1 {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) return true;
        return isSymmHelper(root.left, root.right);
    }
    
    private boolean isSymmHelper(TreeNode left, TreeNode right) {
        if(left == null || right == null) return left == right;
        if(left.val != right.val) return false;
        return isSymmHelper(left.left, right.right) &&isSymmHelper(left.right, right.left);
    }
}
  1. Maximum Depth of Binary Tree
    Recursive[遞歸post-order 分治Divide&Conquer dfs來(lái)upwards累積]
class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null) return 0;
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}
  1. Balanced Binary Tree
    Recusive[遞歸post-order dfs 分治Divide&Conquer 來(lái)upwards累積height]
class Solution {
    public boolean isBalanced(TreeNode root) {
        return dfsHeight(root) != -1;
    }
    
    private int dfsHeight(TreeNode root) {
        // post-order dfsly check from left-bottom and accumulate max_height upwards
        // meanwhile, check if |left_height - right_height)| > 1 for early stop
        
        if(root == null) return 0;
        
        int left_height = dfsHeight(root.left);
        if(left_height == -1) return -1;
        
        int right_height = dfsHeight(root.right);
        if(right_height == -1) return -1;
        
        if(Math.abs(left_height - right_height) > 1) return -1;
        
        return Math.max(left_height, right_height) + 1;
    }
}
  1. Minimum Depth of Binary Tree
    遞歸post-order 分治Divide&Conquer dfs來(lái)upwards累積
class Solution {
    public int minDepth(TreeNode root) {
        if(root == null) return 0;
        int left = minDepth(root.left);
        int right = minDepth(root.right);
        return (left == 0 || right == 0) ? left + right + 1: Math.min(left,right) + 1;
    }
}
  1. Binary Tree Postorder Traversal
    Recursive
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new LinkedList<Integer>();
        postHelper(root, list);
        return list;
    }
    public void postHelper(TreeNode root, List<Integer> list) {
        if(root == null) return;
        postHelper(root.left, list);
        postHelper(root.right, list);
        list.add(root.val);
    }
}
  1. Count Univalue Subtrees [good example]
    遞歸 post-order 分治Divide&Conquer upwards上傳
public class Solution {
    public int countUnivalSubtrees(TreeNode root) {
        int[] count = new int[1];
        helper(root, count);
        return count[0];
    }
    
    private boolean helper(TreeNode node, int[] count) {
        if (node == null) return true;

        // divide
        boolean left = helper(node.left, count);
        boolean right = helper(node.right, count);
        
        // conquer (ifSame(boolean left, boolean right), int count), 
        // and uploads ifSame & count 
        if (left && right) {
            if (node.left != null && node.val != node.left.val) {
                return false;
            }
            if (node.right != null && node.val != node.right.val) {
                return false;
            }
            count[0]++;
            return true;
        }
        return false;
    }
}
  1. Closest Binary Search Tree Value
    Recursive[遞歸(類似post-order) dfs來(lái)upwards累積]
class Solution {
    public int closestValue(TreeNode root, double target) {
        TreeNode next = target < root.val ? root.left : root.right;
        if(next == null) return root.val;
        int val_found = closestValue(next, target);
        return Math.abs(val_found - target) < Math.abs(root.val - target) ? val_found : root.val;
    }
}
  1. Largest BST Subtree
    遞歸 Post-order 分治 Bottom-up向上傳遞
    pack傳遞可以通過(guò)返回值 寫(xiě)法1_a,也可以通過(guò)參數(shù) 寫(xiě)法1_b,都可以的
class Solution1_a {
    
    class Pack {
        int lower;
        int upper;
        int count;
        
        Pack(int lower, int upper, int count) {
            this.lower = lower;
            this.upper = upper;
            this.count = count;
        }
    }
    
    private int result;
    public int largestBSTSubtree(TreeNode root) {
        result = 0;
        helper(root);
        return result;
    }
    
    private Pack helper(TreeNode root) {
        if(root == null) return new Pack(Integer.MAX_VALUE, Integer.MIN_VALUE, 0);
        
        // divide
        // [min, max, count]
        Pack left = helper(root.left);
        Pack right = helper(root.right);
        
        // conquer
        Pack pack = new Pack(Integer.MAX_VALUE, Integer.MIN_VALUE, 1);
        if(left.count != -1 && right.count != -1 && root.val > left.upper && root.val < right.lower) {
            pack.count += (left.count + right.count);
            if(pack.count > result) result = pack.count;
        }
        else {
            //locked
            return new Pack(0, 0, -1);
        }
        
        pack.lower = Math.min(left.lower, root.val);
        pack.upper = Math.max(right.upper, root.val);
        
        return pack;            
    }
}
class Solution1_b {
    
    class Pack {
        int lower;
        int upper;
        int count;
        
        Pack(int lower, int upper, int count) {
            this.lower = lower;
            this.upper = upper;
            this.count = count;
        }
    }
    
    private int result;
    public int largestBSTSubtree(TreeNode root) {
        result = 0;
        helper(root, new Pack(Integer.MAX_VALUE, Integer.MIN_VALUE, 0));
        return result;
    }
    
    private void helper(TreeNode root, Pack pack) {
        if(root == null) return;
        
        // divide
        // [min, max, count]
        Pack left = new Pack(Integer.MAX_VALUE, Integer.MIN_VALUE, 0);
        Pack right = new Pack(Integer.MAX_VALUE, Integer.MIN_VALUE, 0);
        helper(root.left, left);
        helper(root.right, right);
        
        pack.count = 1;
        if(left.count != -1 && right.count != -1 && root.val > left.upper && root.val < right.lower) {
            pack.count += (left.count + right.count);
            if(pack.count > result) result = pack.count;
        }
        else {
            //locked
            pack.lower = 0;
            pack.upper = 0;
            pack.count = -1;
        }
        
        pack.lower = Math.min(left.lower, root.val);
        pack.upper = Math.max(right.upper, root.val);     
    }
}
  1. House Robber III
    [DP思想] 遞歸 Post-order 分治 Bottom-up向上傳遞
class Solution {
    class Result {  
        int cur_max;
        int prev_max;
        Result(int cur_max, int prev_max) {
            this.cur_max = cur_max;
            this.prev_max = prev_max;
        }
    }
    
    public int rob(TreeNode root) {
        Result result = dfsHelper(root);
        return Math.max(result.cur_max, result.prev_max);
    }
    
    private Result dfsHelper(TreeNode node) {
        if(node == null) return new Result(0, 0);
        Result left = dfsHelper(node.left);
        Result right = dfsHelper(node.right);
    
        // consider this one
        int cur_max = left.prev_max + right.prev_max + node.val; 
        // if including negative case
        // int cur_max = Math.max(left.prev_max + right.prev_max, Math.max(left.prev_max, right.prev_max)) + node.val;  
                       
        // don't consider this one
        int prev_max = Math.max(left.cur_max, left.prev_max) + Math.max(right.cur_max, right.prev_max); 
        
        Result result = new Result(cur_max, prev_max);
        return result;
    }
}
  1. Find Leaves of Binary Tree
    遞歸 Post-order 分治 Bottom-up向上傳遞
class Solution {
    public List<List<Integer>> findLeaves(TreeNode root) {
        // build result list
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        
        // bottom-up dfs
        dfsHelper(result, root);
        return result;
    }
    private int dfsHelper(List<List<Integer>> result, TreeNode node) {
        if(node == null) return -1;
            
        int max_dist = 1 + Math.max(dfsHelper(result, node.left), dfsHelper(result, node.right));
        if(max_dist > result.size() - 1) result.add(new ArrayList<Integer>());
        result.get(max_dist).add(node.val);
        
        return max_dist;
    }
}
  1. Most Frequent Subtree Sum
    Recursive
private int postOrder(TreeNode root) {
        if (root == null) return 0;
        
        int left = postOrder(root.left);
        int right = postOrder(root.right);
        
        int sum = left + right + root.val;
        int count = sumToCount.getOrDefault(sum, 0) + 1;
        sumToCount.put(sum, count);
        
        maxCount = Math.max(maxCount, count);
        
        return sum;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末汉买,一起剝皮案震驚了整個(gè)濱河市朱庆,隨后出現(xiàn)的幾起案子炕婶,更是在濱河造成了極大的恐慌裸影,老刑警劉巖滚澜,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爹殊,死亡現(xiàn)場(chǎng)離奇詭異蜕乡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)梗夸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門层玲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人反症,你說(shuō)我怎么就攤上這事辛块。” “怎么了铅碍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵润绵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我胞谈,道長(zhǎng)尘盼,這世上最難降的妖魔是什么憨愉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮卿捎,結(jié)果婚禮上配紫,老公的妹妹穿的比我還像新娘。我一直安慰自己午阵,他們只是感情好躺孝,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著底桂,像睡著了一般植袍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上籽懦,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天于个,我揣著相機(jī)與錄音,去河邊找鬼猫十。 笑死览濒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拖云。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼应又,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宙项!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起株扛,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤尤筐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后洞就,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盆繁,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年旬蟋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了油昂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡倾贰,死狀恐怖冕碟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匆浙,我是刑警寧澤安寺,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站首尼,受9級(jí)特大地震影響挑庶,放射性物質(zhì)發(fā)生泄漏言秸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一迎捺、第九天 我趴在偏房一處隱蔽的房頂上張望井仰。 院中可真熱鬧,春花似錦破加、人聲如沸俱恶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)合是。三九已至,卻和暖如春锭环,著一層夾襖步出監(jiān)牢的瞬間聪全,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工辅辩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留难礼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓玫锋,卻偏偏與公主長(zhǎng)得像蛾茉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子撩鹿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容