剑指offer --- 字符串排列(未结束)

题目

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

用python自带的东西

itertools 是python的迭代器模块,itertools提供的工具相当高效且节省内存。使用这些工具,你将能够创建自己定制的迭代器用于高效率的循环。

https://blog.csdn.net/sjyttkl/article/details/85066710

无限迭代器:
1.count(firstval=0, step=1)创建一个从 firstval (默认值为 0) 开始,以 step (默认值为 1) 为步长的的无限整数迭代器

>>> import itertools
>>>
>>> nums = itertools.count()
>>> for i in nums:
...     if i > 6:
...         break
...     print i
输出的话就是0 ,1,2,3,4,5,6

2.cycle(iterable)对 iterable 中的元素反复执行循环,返回迭代器

>>> import itertools
>>>
>>> cycle_strings = itertools.cycle('ABC')
>>> i = 1
>>> for string in cycle_strings:
...     if i == 10:
...         break
...     print i, string
...     i += 1

不断的输出A,B,C,A,B,C。。。。。

3.repeat(object [,times]反复生成 object,如果给定 times,则重复次数为 times,否则为无限

>>> import itertools
>>>
>>> for item in itertools.repeat('hello world', 3):
...     print item
...
hello world
hello world
hello world

有限迭代器:

1.chain 迭代器能够将多个可迭代对象合并成一个更长的可迭代对象。多个list组合的意思,不用append一直append

>>> my_list = ['foo', 'bar']
>>> numbers = list(range(5))
>>> cmd = ['ls', '/some/dir']

 from itertools import chain
 my_list = list(chain(['foo', 'bar'], cmd, numbers))
 my_list
    ['foo', 'bar', 'ls', '/some/dir', 0, 1, 2, 3, 4]

上面只是举了例子,如果刷题中遇到有人这样做,我们会继续补充,这次我们要用的终点是另一个方法:
组合生成器:
itertools 模块还提供了多个组合生成器函数,用于求序列的排列、组合等:

1.product

2.permutations

3.combinations

4.combinations_with_replacement

permutations 用于生成一个排列,它的一般使用形式如下:

permutations(iterable[, r])
其中,r 指定生成排列的元素的长度,如果不指定,则默认为可迭代对象的元素长度。

>>> from itertools import permutations
>>>
>>> permutations('ABC', 2)
<itertools.permutations object at 0x1074d9c50>
>>>
>>> list(permutations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
>>>
>>> list(permutations('ABC'))
[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]
>>>

那么我们这次核心使用的就是permutations

# -*- coding:utf-8 -*-
import itertools as tl

class Solution:
    def Permutation(self, ss):
        if not ss:
            return []
        res = []
        for i in tl.permutations(ss):
            s = "".join(i)
            if s not in res:
                res.append(s)
        return res

像上面那样做这道题,真的太简单了。不过也想借着这道题,来强化自己的对python的一些库,用这些库可以让我们事半功倍啊。

递归的思想

set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。所以将list转化为set的话,可以自动删去重复的东西。

b = [1,2,3,3,4,45,5,2,31]
c =list(set(b))
比如上面一顿操作后,c就是b中单独的元素了. 顺带写完剑指offer的下面这题:关键就是用了set啦!

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        long =  len(numbers)
        unique = list(set(numbers))
        more = []
        for i in unique:
            if numbers.count(i) > int(long/2):
                more.append(i)
        if not more:
            return 0
        else:
            return more[0]

先找出单独的数
然后计算每个单独的数出现的次数
最后就可以看看啦

思路是:
先固定第一个字符剩下的用递归换位置

第一个肯定是目标,目标就是输出排好序的集合对吧,可能会有重复的吧
第二个终止条件:ss读完了
第三个呢?等价条件不断往里面走对吧。
这个问题有几个点:
第一个都是先固定第一位,然后剩下的进行递归换位置
借着第一位与第二位换位子,然后继续上面的操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值