【递归】字符串的全排列

大致思路:

其实之前一直不能很好地理解全排列,直到看到一个有意思的解释。

全排列是由递归实现的,为了设计递归,只分析“当下”:针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去(每个位置都可以放,所以遍历位置,与之后的每个元素都进行交换);第二是不把这个字符放到组合中去(其实就是和自身交换)。

同理,之后的每个字符都是这样操作。递归实现。临界条件是:当前针对的这个字符到了最后一个,那么此时这个字符串可作为一种可能的结果字符串。

注意点:对于字符串中字符交换函数,记得参数为“引用”类型,因为要实质性地改变字符串;对于结果字符串加入vector存储,要注意避免多个比如“aa”的存储(位置不一样但其实内容一样),方法是用find(查找起始地址,查找结尾地址,要查找的内容)==查找结尾地址 来判断之前不存在该字符串

AC代码:

class Solution {
public:
    vector<string> res;
    vector<string> Permutation(string str) {
        if(str.size()==0)
            return res;
        if(str.size()==1)
        {
            res.push_back(str);
            return res;
        }
        QuanPaiLie(str,0);
        
        //牛客网判题要求按字典序顺序输出
        sort(res.begin(),res.end());
        
        return res;
    }
    
    void QuanPaiLie(string &str,int begin) //这个str也应该传引用,因为递归过程中要有承接关系,而不是重新创副本
    {
        if(begin==str.size()-1)   //不需要递归了
        {
            //注意这个判重很容易忽略,不然容易出现多个aa
            if(find(res.begin(),res.end(),str) == res.end()) //find从begin搜到end说明搜到最后了都没有
            {
                res.push_back(str);
                return ;
            }
        }
        else //还需要递归
        {
            for(int i=begin;i<=str.size()-1;i++)
            {
                swapChar(str,begin,i);
                QuanPaiLie(str,begin+1);
                swapChar(str,begin,i); //记得换回来!!!
            }
        }
    }
    
    void swapChar(string &str,int a,int b) //加引用哟,因为要实质性改变
    {
        char temp=str[a];
        str[a] = str[b];
        str[b] = temp;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_38033475/article/details/91997802