当前位置:   article > 正文

字符串全排列算法_C#版_剑指OFFER_c编程 输入一个长度为 n 由大小写字母组成的字符串,打印出该字符串中字符的所有排

c编程 输入一个长度为 n 由大小写字母组成的字符串,打印出该字符串中字符的所有排

字符串全排列算法_C#版_剑指OFFER

题目描述

题目描述
输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。
数据范围: n < 10n<10
要求: 空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)
输入描述: 输入一个字符串,长度不超过10,字符只包括大小写字母。

在这里插入图片描述

思路

显然此题为递归思维。固定一个字符,依次与剩下的字符进行交换,然后固定下一个,思想类似于排列…
首先,将字符串分为两个部分,一部分为用于交换的固定串,一部分为等待交换的交换串。为方便讲解,将固定串中字符称为固定字符,交换串中的字符称为交换字符
那么其递归顺序是这样的:

  1. 固定第一个字符,与剩下交换串substr依次交换
  2. 将substr视做第一个字符串,固定substr的第一个字符,进行操作1,直到substr长度为0,结束递归
  3. 第一个固定字符使用完毕,开始固定第二个字符,与剩下的字符串substr依次交换字符值
  4. 重复上述步骤,直至所有字符都固定过

此时,会有重复字符串的问题。固定字符与交换字符相同,那就白交换了。这时可以设置不相同时才交换。
但还是会有重复问题:

比如a b1 b2,
按照思路,
第一轮
固定a
交换一次后,得到b1 a b2,substr (a,b2 ) 交换后得到b1 b2 a,(第二步)
a b1 b2交换第二次,得到b2 b1 a,此时就重复了

此时发生重复问题是因为进入递归后,substr可当做一个独立字符串,前面的固定字符串无法影响substr产生的交换字符串,显而易见地,substr字符串拥有的字母与数量相同,则会产生重复的排列
为了解决这个问题,就提前掐断字母全都相同的substr。
判断当前交换字符,与固定字符之间的串(称为中间串)是否有与其重复的字符,如果有,就取消交换。

比如a b1 c b2 d,
按照思路,
第一轮固定a,
交换第一次得到,b1 a c b2 ,
substr (a,c,b2 ) 总会得到交换串 b2,c,a
而a与b2交换后得b2 b1 c a ,此字符串进入递归后substr(b1,c,a) 肯定会产生重复排列

using System.Collections.Generic;
using System;
class Solution
{
    public List<string> Permutation(string str)
    {
        // write code here
        List<string> res = new List<string>();
        if(str.Length==0)return res;
        recursion(0,str,ref res);
        return res;
    }
    public void recursion(int fixedIdx,string str,ref List<string> res)
    {
        // write code here
        //注意 string是不可修改的,故要转换为字符串数组
        char [] newstr = str.ToCharArray();
        res.Add(str); //添加初始串
        int curIdx;
        while(fixedIdx<str.Length)
        {   //固定字符依次向前推进
            for(curIdx=fixedIdx+1;curIdx<str.Length;curIdx++)
                {
                   if(is_swap(fixedIdx,curIdx,newstr)){
                        swap(fixedIdx,curIdx,ref newstr);   //交换
                        recursion(fixedIdx+1,new string(newstr),ref res); //从此串确定的位置后一位开始递归
                        newstr=str.ToCharArray(); //复原
                    }
                }
            fixedIdx++;
        }
    }
     //防止与前面会产生的交换串重复, 递归字符串拥有的字母与数量相同,则会输出重复的排列
     //保证相似的字符串只会输出一次
    public bool is_swap(int fixedIdx,int curIdx,char[] newstr)
    {
        int idx=curIdx-1;  //依次比较中间串是否有相等字符,若有返回false,跳过这轮交换
        while(idx>=fixedIdx)
        {
            if(newstr[idx]==newstr[curIdx])
                return false;
            idx--;
        }
        return true;
    }
    //交换
    public void swap(int fixedIdx,int idx,ref char[] substr)
    {
        char tmp=substr[fixedIdx];
        substr[fixedIdx]=substr[idx];
        substr[idx]=tmp;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/310188
推荐阅读
相关标签
  

闽ICP备14008679号