NO27、字符串的排列(经典题目,超级经典)

博客围绕字符串排列这一经典题目展开,介绍了两种实现方法。一是使用next_permutation函数返回全排列,需先排序,该函数按字典序产生排列;二是DFS + 回溯算法,但作者表示还未完全理解。最后提到可在公众号获取笔记PDF版本。
27、字符串的排列 经典题目,超级经典

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

输入描述:

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

示例1
输入

"ab"

返回值

["ab","ba"]
1、一个很奇特的函数next_permutation

返回全排列,使用方法如下所示,必须要进行排序才可以:

执行用时:52 ms, 在所有 C++ 提交中击败了91.01%的用户

内存消耗:17.9 MB, 在所有 C++ 提交中击败了100.00%的用户

    vector<string> permutation(string s) {

    if(s.size()==0) return vector<string>();
        
	vector<string> result;
	sort(s.begin(), s.end());
	do {
		result.push_back(s);
	} while (next_permutation(s.begin(),s.end()));

	return  result;
    }
#include <stdio.h>
#include <algorithm>
using namespace std;
int main(){
    int n;
    while(scanf("%d",&n)&&n){
        int a[1000];
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        do{
            for(int i=0;i<n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }while(next_permutation(a,a+n));
    }
    return 0;
}

例如输入

3

1 0 2

如果有sort()

输出为

0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0

若无

则输出为

1 0 2
1 2 0
2 0 1
2 1 0

发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序

2、DFS+回溯算法 还没有完全理解
class Solution {
public:
    vector<string>  result;
    void PermutationCore(string &s,int begin,int end){
        if(begin == end){
            result.push_back(s);
            return ;
        }
        unordered_map<int,int> visited;
        for(int i = begin; i<= end; ++i){
            if(visited[s[i]] == 1) continue;
            swap(s[i],s[begin]);
            PermutationCore(s,begin+1,end);
            swap(s[i],s[begin]);
            visited[s[i]] =1;

        }

    }
    
    vector<string> Permutation(string str) {
    if(str.size()==0) return vector<string>();
    
    PermutationCore(str,0,str.size()-1);
    sort(result.begin(),result.end());
	return  result;
    }
};
二刷:
1、好题,不开玩笑,最后还要排序,要求是按照字典序输出的
class Solution {
public:
    vector<string>  result;
    void PermutationCore(string &s,int begin,int end){
        if(begin == end){
            result.push_back(s);
            return ;
        }
        unordered_map<int,int> visited;
        for(int i = begin; i<= end; ++i){
            if(visited[s[i]] == 1) continue;
            swap(s[i],s[begin]);
            PermutationCore(s,begin+1,end);
            swap(s[i],s[begin]);
            visited[s[i]] =1;
 
        }
 
    }
     
    vector<string> Permutation(string str) {
    if(str.size()==0) return vector<string>();
     
    PermutationCore(str,0,str.size()-1);
    sort(result.begin(),result.end());
    return  result;
    }
};

美女帅哥们如果觉得写的还行,有点用的话麻烦点个赞或者留个言支持一下阿秀~
如果觉得狗屁不通,直接留言开喷就完事了。

需要该笔记PDF版本的去个人公众号【拓跋阿秀】下回复“阿秀剑指offer笔记”即可。

### C++ STL 经典编程题目与习题 以下是几个经典C++ STL 编程题目及其解析: #### 1. **大小写转换** 通过 `set` 实现单词去重功能,并利用 `tolower()` 函数完成字母的小写化处理。此问题的核心在于掌握如何使用集合容器以及字符操作函数。 ```cpp #include <bits/stdc++.h> using namespace std; int main(){ int n; cin >> n; set<string> st; for(int i = 1; i <= n; ++i){ int opt; string word; cin >> opt >> word; if(opt == 0){ for(int j = 0; j < word.length(); ++j){ word[j] = tolower(word[j]); } st.insert(word); } else { if(st.count(word)){ cout << "Yes" << endl; } else{ cout << "No" << endl; } } } return 0; } ``` 这段代码展示了如何使用 `std::set` 来存储唯一的字符串并判断是否存在某个特定的词[^1]。 --- #### 2. **约瑟夫环问题** 这是一个典型的队列应用案例,用于解决循环淘汰类的问题。程序模拟了一个简单的酒桌游戏场景,其中玩家按顺序报数直到某个人被淘汰为止。 ```cpp #include <bits/stdc++.h> using namespace std; int main(){ int n, m; cin >> n >> m; queue<int> q; for(int i = 1; i <= n; i++) q.push(i); int j = 1; while(q.size() != 1){ if(j % m == 0) q.pop(); else{ q.push(q.front()); q.pop(); } j++; } cout << q.front(); return 0; } ``` 上述实现方式简洁明了地解决了约瑟夫环问题,体现了标准模板库中 `queue` 容器的强大之处[^2]。 --- #### 3. **消息队列管理** 本题涉及优先级队列的应用,要求根据给定指令动态调整消息列表中的元素次序。具体来说,“PUSH” 命令需附带数据项和对应的权重值;而每次执行 “POP”,应返回当前最高优先级的消息内容或者默认提示符 `"NULL!"` 若无任何待处理项目存在的话。 ```cpp #include <bits/stdc++.h> using namespace std; struct Message { string data; int priority; }; bool operator<(const Message& a, const Message& b){ if(a.priority != b.priority) return a.priority < b.priority; return true; } priority_queue<Message> pq; int main(){ string cmd; while(cin >> cmd){ if(cmd == "PUSH"){ string str; int pri; cin >> str >> pri; pq.push(Message{str, pri}); } else if(cmd == "POP"){ if(pq.empty()) cout << "NULL!\n"; else{ cout << pq.top().data << "\n"; pq.pop(); } } } return 0; } ``` 这里运用到了自定义比较运算符来控制堆内部节点排列逻辑,从而满足业务需求关于不同等级间相对位置安排的规定[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拓跋阿秀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值