1.二叉搜索树与双向链表
思路:二叉搜索树中序遍历是排好序的,按照中序遍历的顺序,当遍历转换到根节点时,左子树已经转换为一个排序的链表,并且处在链表中的最后一个节点是当前值最大的节点。我们把倒数第二个节点和根节点连接起来,此时链表的最后一个节点就是根节点。接着去遍历转换右子树,并把根节点和右子树中最小的节点连接起来。考虑使用递归。

/*
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)
    {
        TreeNode *Last=nullptr;//指向链表最后一个节点
        helper(pRootOfTree,&Last);
        TreeNode *Head=Last;
        while(Head!=nullptr&&Head->left!=nullptr)
        {
            Head=Head->left;//返回头结点
        }
        return Head;
    }
    void helper(TreeNode* pNode,TreeNode** Last)//注意参数写法
    {
        if(pNode==nullptr) return;
        TreeNode *cur=pNode;
        if(cur->left!=nullptr)
            helper(cur->left,Last);//遍历左子树
        cur->left=*Last;//根节点左指针指向左子树最大的数(右叶子)
        if(*Last!=nullptr)
            (*Last)->right=cur;//右叶子不为空,其右指针指向根节点
        *Last=cur;//为空,直接等于根节点
       if(cur->right)
            helper(cur->right,Last);//遍历右子树
    }
};

2.序列化二叉树
思路:前序遍历序列化,利用递归。反序列化同样使用递归,如果输入不是数字,说明此节点为null,跳过;如果是数字,进行反序列化递归。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<int> buf;
    void dfs1(TreeNode *root) {
        if(!root) buf.push_back(0xFFFFFFFF);
        else {
            buf.push_back(root->val);
            dfs1(root->left);
            dfs1(root->right);
        }
    }
    TreeNode* dfs2(int* &p) {
        if(*p==0xFFFFFFFF) {
            p++;
            return NULL;
        }
        TreeNode* res=new TreeNode(*p);
        p++;
        res->left=dfs2(p);
        res->right=dfs2(p);
        return res;
    }
    char* Serialize(TreeNode *root) {
        buf.clear();
        dfs1(root);
        int bufSize=buf.size();
        int *res=new int[bufSize];
        for(int i=0;i<bufSize;i++) res[i]=buf[i];
        return (char*)res;
    }
    TreeNode* Deserialize(char *str) {
        int *p=(int*)str;
        return dfs2(p);
    }
};

3.字符串的排列
思路:把字符串分成两部分,一部分是字符串的第一个字符,另一部分是第一个字符以后的所有字符;然后求阴影部分(除第一个字符)的子字符串的排列(递归);然后拿第一个字符和它后面的字符逐个交换。

class Solution {
public:
    vector<string> Permutation(string str) {
        vector<string> result;
        if(str.empty()) return result;
        exChange(str,result,0);
        sort(result.begin(),result.end());
        return result;     
    }
    void exChange(string str,vector<string> &result,int begin)
    {
        if(begin==str.size()-1)
        {
            if(find(result.begin(),result.end(),str)==result.end())
            {
                result.push_back(str);//不重复的放进去
            }

        }
        else
        {
          for(int i=begin;i<str.size();i++)
           {
            swap(str[i],str[begin]);
            exChange(str,result,begin+1);//递归排列剩下的序列
            swap(str[i],str[begin]);//换回来再换回去
            }  
        }

    }
    void swap(char &x,char &y)
    {
        char z;
        z=x;
        x=y;
        y=z;
    }
};