C++实现实现全排列

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

思路:
回溯+递归
以一个ABC的图为例。首先从ABC中选一个,可以选A、B、C分别是第二层的绿色表示。然后则剩余BC 、AC和BA。对于每一个分支,依次选择其中一个与之前的进行连接,过程直到被选集只剩下一个的时候。这个过程本质上是回溯。
在这里插入图片描述那么代码中怎么实现“选一个”和拼接的动作呢?
“选一个”实际上是通过循环遍历完成的。for循环,从开始到结束依次取。怎么完成的拼接呢?本质上是交换完成的。一个个“选一个”和拼接又是怎么完成的?通过递归完成。
【以ACB为例】
第一次递归,传入ABC,开始i为0,和长度3
for循环写作for(int j = i ; j < n ; j++)首先是j=0,也就是选了A作为第一个,然后完成交换,字符串仍为ABC,递归下一层,也就是从BC中选一个后与A连接。所以第二次递归,传入还是ABC,但是开始为1,总长度仍为3
此时,j = 1 但不是要举的ABC的例子,所以跳过。当 j = 2 时,意味着选择C作为当前要排在A后的,怎么实现排在A后?通过交换完成,把C换做BC串的第一个,成为CB。字符串变为ACB。此时继续递归。
第三次递归,开始i为2,总长度为3,意味着此时是最后一个,最后一个不需选择,直接拼接,可以将当前的结果作为一个对象,完成ACB的生成。
然后依次返回到递归调用处,重新把字母交换回来,恢复原状。

因此,字母的全排列代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;

void per(string str, int i , int n){
    if (i == n-1) {
        cout << str << endl;
        return;
    }
    for (int j = i ; j < n ; j++) {
        swap(str[i], str[j]);
        per(str, i+1, n);
        swap(str[i], str[j]);
    }
}

int main(){
    per("ABC", 0, 3);
    return 0;
}

力扣题目代码如下:

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string s = "";
        if(strs.size() == 0) return s;
        int length = strs[0].size();
        for(int i = 0 ; i < strs.size() ; i++){
            if(strs[i].size() < length) length = strs[i].size();
        }
        int m = 0 , n = 0 ; char temp;
        while(n < length){
            temp = strs[0][n];
            for(m = 1 ; m < strs.size() ; m++){
                if(strs[m][n] != temp) return s;
            }
            s+=temp;
            n++;
        }
        return s;
    }
};
  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值