二叉搜索树与双向链表
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:通过中序遍历将节点保存下来,这里提供一种递归合并链表的解题思路:递归左右子树,遍历左子树到最后一个节点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;
}
};