JZ27_字符串的排列

JZ27_字符串的排列

知识点:递归、全排列
题目链接

题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

示例1
输入:“ab”
返回值: [“ab”,“ba”]

解题思路

方法一 :每次找下一个全排列

  1. Leetcode刷题笔记 31. 下一个排列一样的思路
  2. 首先从尾向头找 str[i] < str[i+1] ,若找到说明 [i+1,n) 都是降序的
  3. 再从尾从头找第一个 比str[i]大的 str[j] > str[i]
  4. 交换str[i] 和 str[j] 再翻转区间[i+1,n)的 让他变成升序
  5. 这样就得到了下一个升序
 举例
 3415731
 str[i] = 5
 str[j] = 7
 swap 3417531
 reverse 3417135

方法二: 使用递归 每次交换一个字符串

  1. 递归跳出条件:如果长度到达了要求 用find函数 或者 set 来去重 把答案放入
  2. 递归步骤: 从长度到最长长度 遍历交换一个位置 相当于 我们自己手动模拟 先定下第一个数 再对后面的改变
  3. 递归完记得回溯

方法三: 可以弄一个空的字符串 每次往里面填数据

代码

#include "cheader.h"
class Solution {
public:
    vector<string> Permutation(string str) {
        vector<string> ans;
        sort(str.begin(),str.end());
        ans.push_back(str);
        while(1){
            str = nextstr(str);
            if(str == "none")
                break;
            else
                ans.push_back(str);
        }
        return ans;
    }
    string nextstr(string str){
        int i = str.size()-2;
        while(i>=0 && str[i] >= str[i+1])
            i--;
        if(i==-1)
            return "none";
        int j = str.size()-1;
        while(j>=0 && str[j] <= str[i])
            j--;
        swap(str[i],str[j]);
        reverse(str.begin()+i+1, str.end());
        return str;
    }
};
class Solution2 {
public:
    vector<string> ans;
    vector<string> permutation(string s) {
        dfs(s,0);
        return ans;
    }
    void dfs(string s,int index){
        if(index == s.size()-1){
             ans.push_back(s);
             return ;
        }
        set<int> st;
        for(int i = index; i < s.size(); i++){
            if(st.find(s[i]) != st.end()) 
                continue; // 重复,因此剪枝
            st.insert(s[i]);
            swap(s[i],s[index]);
            dfs(s,index+1);
            swap(s[index],s[i]);
        }
        return;
    }
};
class Solution3 {
public:
    vector<vector<int>> ans;
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> tmp;
        vector<int> vis(nums.size(),0);
        sort(nums.begin(),nums.end());
        dfs(tmp,nums,vis);
        return ans;
    }
    void dfs(vector<int>& tmp,vector<int>& nums,vector<int>& vis){
        if(tmp.size() == nums.size()-1){
            ans.push_back(tmp);
            return ;
        }
        if(tmp.size() > nums.size())
            return ;
        for(int i = 0; i < nums.size(); i++){
            if(vis[i] == 0){
                vis[i] = 1;
                tmp.push_back(nums[i]);
                dfs(tmp,nums,vis);
                tmp.pop_back();
                vis[i] = 0;
            }
        }
    }
};
int main()
{
    Solution s;
    string str = "3124";
    vector<string> ans = s.Permutation(str);
    for(string s: ans)
        cout<<s<<endl;
    return 0;
}

今天也是爱zz的一天!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值