二叉樹翻轉(分治思想的典型)

大盜發表於2019-03-03

二叉樹翻轉是一道比較簡單,但是又非常有意思的演算法問題,當然了,對於應屆生或是正在學習演算法的學生來說,這道題顯然是非常簡單的,但對於有著多年技術經驗的工程師,可能就不一定能寫的出來(我指的是白板面試這類在紙類介質上進行書寫的情況。)

1. 題目


話不多說,我們直接看題:

Invert a binary tree. 
     4
   /   
  2     7
 /    / 
1   3 6   9
to
     4
   /   
  7     2
 /    / 
9   6 3   1複製程式碼

這個問題的文字描述,簡單說來就是將二叉樹的左右子樹全部翻轉過來,使原二叉樹的左子樹稱為新二叉樹的右子樹。

這個問題看起來是不是很簡單?但有趣的是,有人是這樣評價這個問題:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.

產生這種問題的原因可能是多樣的,不過無論是什麼原因,對於一個應屆生或是正在學習演算法的學生來說,都是必須要忽略的,因為如果不會寫演算法對應的程式碼,我們又如何判斷你是真的懂這個演算法?總不能讓我相信你的一面之詞不是?

2. 解決程式碼


//這是遞迴方法
TreeNode* invertTree(TreeNode* root) {
    if (!root) return nullptr;
    else {
        TreeNode *temp = root->left;
        root->left = root->right;
        root->right = temp;
    }
    invertTree(root->left);
    invertTree(root->right);

    return root;
}

//進行遞迴簡化
TreeNode* invertTree(TreeNode* root) {
    if (root) {
        invertTree(root->left);
        invertTree(root->right);
        std::swap(root->left, root->right);
    }
    return root;
}

//非遞迴形式@chammika
TreeNode* invertTree(TreeNode* root) {
    std::stack<TreeNode*> stk;
    stk.push(root);

    while (!stk.empty()) {
        TreeNode* p = stk.top();
        stk.pop();
        if (p) {
            stk.push(p->left);
            stk.push(p->right);
            std::swap(p->left, p->right);
        }
    }
    return root;
}複製程式碼

3. 解題思路


這一道題,一眼看過去,我們立刻就能得到的資訊是:

  • 這是一個二叉樹,與二叉樹有關的演算法基本都與遞迴相關聯。
  • 這個二叉樹是以連結串列形式實現的。
  • 翻轉,將左子樹變為右子樹,右子樹變為左子樹。
  • 翻轉的操作僅需改變雙親指標。

簡化我們所得到的資訊,即得到,我們需要通過遞迴來改變雙親的指標以實現翻轉操作。

其實這道題算的上是一道應用分治思想的典型題了,我們按照如下步驟進行演算法的編寫:

  • 分解問題:二叉樹的翻轉涉及到左右子樹,故而我們可以採用二分的方式進行分解,先進行左子樹的遍歷翻轉,再進行右子樹的遍歷翻轉。
  • 求解問題:當我們一次遍歷到某一為nullptr的葉結點時,返回上一非空結點,交換這一非空結點的左右子樹,此為遞迴時的出口
  • 合併問題:尋著遞迴鏈向上回溯,針對每一個分解後的問題進行合併(無相關程式碼,由遞迴性質決定)。

綜上,我們可以看到,先設計一個遞迴出口,何時能夠讓遞迴終止if (!root) return nullptr; 此為出口的一種,我們也可以將遞迴出口設定在最後,此時我們需要設定的是滿足什麼條件才能開始遞迴if (root) { /* ... */ } 條件不滿足時,我們可以開始遞迴的回溯return root

總的來說,這道題還是非常簡單的(手動滑稽)。

相關文章