老子的全排序

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

老李见和尚赢了自己的酒,但是自己还舍不得,所以就耍起了赖皮,对和尚说,光武不行,再来点文的,你给我说出来1-8的全排序,我就让你喝,这次绝不耍你,你能帮帮和尚么?

输入描述:  无

输出描述:  1~8的全排列,按照全排列的顺序输出,每行结尾无空格。

拿到这个题,真的第一想法就是,太短了吧~~

果然从小到大,理科有关的,只要文字短,就不是一个简单的事情。


 首先放上自己的代码,但是在这个题里,我的这个代码是行不通的。

思路大概是这样的:

让最后一位数往前走一位,直到走到最后变回自己原来的样子就是全排列,比如说
     1 2 3
     1 3 2
     3 1 2
     3 2 1
     2 3 1
     2 1 3
     1 2 3    
     最后一位和前面第一个位置是完全一样的,那么可以用数组来存放这些数。


按照这个方案,虽然说也可以求出全排列,但不符合题目的要求(按照全排列的顺序输出

因此我觉得十分的苦恼,寻求一个能按照顺序输出的。

#include <stdio.h>
#include <string.h>

void swap(char brr[],int n){
    char tep;
    tep = brr[n];
    brr[n]=brr[n-1];
    brr[n-1]=tep;
}

int main(){
    int i=0;
    char arr[9]={'1','2','3','4','5','6','7','8','\0'};
    char brr[9]={'1','2','3','4','5','6','7','8','\0'};
    int n=7;
    do{
         for(i=0;i<8;i++){
         	if(i!=7)
             	printf("%c ",brr[i]);
            else
            	printf("%c\n",brr[i]);
         }
        swap(brr,n);
        if(n>1)
        	n--;
		else
			n=7; 
    }while(strcmp(arr,brr)!=0);  
}

 于是会玩计算机的我,选择了上网搜(这叫做把计算机用到有用的地方。)

得到了如下的两种方案,然后我就又开始为自己大一偷的懒难过了。


方案一: 

大概就是明白了为什么一定要学stl,直接拿来用真的好方便就是说。

这个就简单简单,自己意会一下吧~主要是就是while里面的那个函数。

next_permutation函数用法举例_沐妖的博客-CSDN博客_nextpermutation函数

放个链接,你们自己学吧~

#include<bits/stdc++.h>
 
using namespace std;
 
int main ()
{
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8};
 
    do
    {
        for(int i = 0; i < 8; i++)
        {
            printf(i == 7 ? "%d\n" : "%d ", a[i]);
        }
    }
    while(next_permutation(a, a + 8));
 
    return 0;
}


方案二: 

这个是真的可以称为大神,简短的代码中蕴含着伟大的哲学。 我也是费了好久才能明白他大概是什么意思。

话不多说,先看看代码吧~~~感受一下简短代码的魅力。

#include<stdio.h>
// #include <iostream>
// using namespace std;
int p[10];
int a[10];
int cnt=0;
void dfs(int k){
    if (k>8){
        for (int i =1 ; i <= 7 ; i ++ )
            printf("%d ",a[i]);
        printf("%d\n",a[8]);
        return ;
    }
    for (int i = 1 ; i <= 8 ; i ++ )
       if (!p[i]){
           p[i]=1;
           a[k]=i;
           dfs(k+1);
           p[i]=0;
       }
}
int main(){
    dfs(1);
    return 0;
}

在这里是解析:

首先我们可以看到,这里运用的是递归的方案。这是显然可得的。

但是除了递归还有其他的小细节。

众所周知,递归其实就是栈。那么

第一步,从1-8依次压入栈中

假设我们仔细观察,我们就能看到有一个地方是有一点点与众不同的,就是我们的a[k]=i;

现在假设我们只有123三个数字。我们来例举一下现在的情况。

第一次的时候,我们完整得输出我们的 1 2 3

第二次的时候,我们的 3 和 2就需要换位置,那么换位置这个事情是怎么样进行的呢?

主要用的是回溯。我们输出一次 1 2 3之后,由于我们传递过去的是k+1,也就是说,当k+1=3的时候就可以输出了,那么回到函数位置的时候,我们的k值就回到了1

大概是这个意思吧!p[i]是标记函数。

然后我们就进行for循环,因为我们在进入递归前的i为2,所以,我们递归之后,我们的i++也就是3了,那么我们在进行a[k]=i的时候就可以把3放在了2的位置。

总结:8位数的话,也应该是同样的理论,如果还是不清楚的话,这边建议调试看看~


呼!写完了,真是为难我的脑袋瓜子了,果然脑子这种东西是用进废退的,要多动脑勤思考。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值