5.16打卡:劍指 offer兩題:二叉搜索樹與雙向鏈表/字符串的排列

二叉搜索樹與雙向鏈表

題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

思路:通過中序遍歷將節點保存下來,這裏提供一種遞歸合併鏈表的解題思路:遞歸左右子樹,遍歷左子樹到最後一個節點lastNo,隨後將left list root right list拼接起來即可

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree==NULL) return NULL;
        auto left = Convert(pRootOfTree->left);
        auto right=Convert(pRootOfTree->right);
        auto lastNode = findLastNode(left);
        if(lastNode==NULL) left = pRootOfTree;
        else
        {
            pRootOfTree->left = lastNode;
            lastNode->right = pRootOfTree;
        }
        if(right==NULL)
        {
            pRootOfTree->right = NULL;
            return left;
        }
        pRootOfTree->right = right;
        right->left = pRootOfTree;
        return left;
    }

    TreeNode* findLastNode(TreeNode* head)
    {
        if(head==NULL) return NULL;
        auto cursor = head;
        while(cursor->right!=NULL) cursor = cursor->right;
        return cursor;
    }
    
};

字符串的排列

題目描述

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

輸入描述:

輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。

思路:假設我們有ABC三個字符,一般的操作是固定A不動,然後交換B與C,從而得到"ABC" 和 "ACB"
同理,對於"BAC"、"BCA" 、"CAB"和"CBA"是同樣道理

遞歸三部曲:

  1. 遞歸函數的功能:Permutation(string str, set<string>& res, int begin),交換兩個字符
  2. 遞歸終止條件:索引已經指向str最後一個元素時

但是,對於"ABB"來說,就會有重複,所以我們用set可以進行去重,並且可以達到按字母順序排序。

class Solution {
public:
    //回溯法
    vector<string> Permutation(string str) {
        vector<string> result;
        //空字符串直接返回result
        if(str.size()==0) return result;
        //用一個集合進行存儲,避免重複,同時默認排好序了
        set<string> res;
        Permutation(str,res,0);
        //將集合中的元素依次加入result
        for(auto &e:res) result.push_back(e);
        return result;
    }
    
    void Permutation(string str, set<string>& res, int begin)
    {
        //遞歸結束條件:索引已經指向str最後一個元素時
        if(begin==str.size()-1) res.insert(str);
        else
        {
            for(int i = begin; i < str.size(); i ++)
            {
                //依次進行交換
                swap(str[begin],str[i]);
                Permutation(str,res,begin+1);
                //復位
                swap(str[begin],str[i]);
            }
        }
    }
    //交換兩個字符
    void swap(char& first,char& second)
    {
        char t = first;
        first = second;
        second = t;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章