二叉搜索樹與雙向鏈表
題目描述
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
思路:通過中序遍歷將節點保存下來,這裏提供一種遞歸合併鏈表的解題思路:遞歸左右子樹,遍歷左子樹到最後一個節點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"
是同樣道理
遞歸三部曲:
- 遞歸函數的功能:
Permutation(string str, set<string>& res, int begin),交換兩個字符
- 遞歸終止條件:索引已經指向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;
}
};