java打印结果横向排列_Day27:字符串的排列

85f0602a96c98d45e8a9d1a63b99b005.png

剑指Offer_编程题——字符串的排列

题目描述:

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

输入描述:

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

具体要求:

时间限制: C/C++ 1秒,其他语言2秒
空间限制: C/C++32M,其他语言64M

具体思路:

思路一

这也是我们经常想到的思路,也就是固定交换法。即:先固定一个字母不变,通常固定在子串的首位,如abc固定a,对bc再进行全排列,bc串中固定b,对c进行全排列。交换即在a固定的情况下已经对bc子串进行了全排列之后,那么就将a与第二位的b交换变成bac,此时再回到了固定的步骤,只需固定b,对字串ac进行全排列。依此类推,直至交换完。这个是好想,但是有一个小坑需要我们注意,那就是有重复元素的情况,如aab,那么只需加一个判定条件,当交换的元素相同就无需进行交换,直接跳过即可。我们用python来实现这一思路。

class 

代码效果图如图所示:

c58afca2a958af316a95e89a4e4ccb16.png

思路二

列出所有字符串用递归求解,对于n个字符串的排列问题,如果能生成n-1个元素的全部排列结果,就能生成n个元素的全部排列结果。接下来我们用Java来实现比较方便。由于java中专门有一个排序集合——TreeSet。又因为题目中要求返回ArrayList类型,故将TreeSet中的元素全部加入到ArrayList中。

import 

代码效果图如图所示:

3f2df16dac15fa4a7d9011463761ea66.png

思路三

这种想法是最难想到的,但是代码量以及运行效果确实最优的。留一排他法:留一即将一位留出来,排他即将剩下的进行全排列,然后将留出来的分别拼到全排列串的首位。如abc,留a,排bc得bc、cb,拼:a+bc,a+cb,结果,abc,acb。再留b,排ac……依此类推。具体我们用python将其实现

class 

代码效果图如图所示:

38a85faaa01cac5f84c779b8d0c35848.png

总结

本道题主要考察字符串的排序,这里考察的知识点是字符串以及动态规划和递归的相关知识。我们首先想到的思路就是固定一个字母,然后遍历调换其他两个字母,这里有一个小坑就是当字符重复的时候,直接跳过交换。思路二是用到了我们Java中的TreeSet有序集合。大大降低了难度。不过我们题目要求的是返回ArrayList,因此我们还需要将TreeSet集合的元素再放入到ArrayList中。思路三是不好想,但是效果最佳,应用的留一排他法,大大减少了代码量和运行时间。因此,我们在做题的时候,应该多次尝试各种方法,扩展自己的思维,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!

参考文献

[1]lingongheng

[2]Valonecium

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值