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;
    }
};

 

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