python_lintcode_简单题_8旋转字符_420报数_197排列序号

8 旋转字符

题目:

给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转)

样例
对于字符串 “abcdefg”.
offset=0 => “abcdefg”
offset=1 => “gabcdef”
offset=2 => “fgabcde”
offset=3 => “efgabcd”

思路:

一开始以为输入的字符串,直接用字符串的连接。后面一直出现WA,提示输入的是列表list,连接无法使用。
后面看网上用了list的pop()和insert()

代码

class Solution:
    # @param s: a list of char
    # @param offset: an integer
    # @return: nothing
    def rotateString(self, s, offset):
        # write you code here
        #输入的char/是个list
        if not offset: 
            return
        if not s: 
            return
        n = len(s)
        offset = offset%n    #求余,处理offse>n的情况
        for i in range(offset):
            t = s.pop()     #取list的最后一个值
            s.insert(0,t)   #list的第一个插入t,且lsit长度不变

420报数

题目:

报数指的是,按照其中的整数的顺序进行报数,然后得到下一个数。如下所示:

1, 11, 21, 1211, 111221, …
1 读作 “one 1” -> 11.
11 读作 “two 1s” -> 21.
21 读作 “one 2, then one 1” -> 1211.
给定一个整数 n, 返回 第 n 个顺序。

注意事项:整数的顺序将表示为一个字符串。

样例:给定 n = 5, 返回 “111221”.

思路

  • 由n,从第一个‘1’到第n-1个数的报数结果,比如n=3是第二个数11的输出two one->21
  • 两次循环,外循环是n-1次报数,内循环是每一次报数结果。
  • 内循环从第一个数开始查找是否与之相同,相同则计数器加一,不同重新指向到下一个字符。
  • 这里的操作都是对字符串进行操作。

代码

class Solution:
    # @param {int} n the nth
    # @return {string} the nth sequence
    def countAndSay(self, n):
        # Write your code here
        #初始化字符串
        str1='1'
        for x in range(n-1):

            tmp=str1[0]  #读取上一个报数的首字符
            result=''   #对下一个报数结果初始化
            count =0    #初始化计数器
            for i in range( len(str1)):
                if tmp==str1[i]:    #若与前一个则计数+1
                    count+=1
                else:               #若不同则tmp指向下一个数字,count=1        
                    result=result+str(count)+tmp   #输出的是字符串,需要对count转str
                    count=1
                    tmp=str1[i] 
            str1=result+str(count)+tmp    
        return str1

197排列序号

题目

给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。

样例
例如,排列 [1,2,4] 是第 1 个排列。

思路

  • 字典序:对于数字1、2、3……n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是 54321。

找规律
- 例如:[4,2,3,1]
- 第一个数字是4 字典序的话,必须[1,…],[2,…],[3,…]才到[4,…],前面需要(3=len([4,2,3,1])-1;A33=3*2)

3*2*3=12

删除第一个4,则剩下则[2,3,1]

  • 第二个是2,经历[1,..]才到[2,..],前面需要(2=len([2,3,1])-1;A22=2*1)
2*1*1=2

删除第二个2,则剩下则[3,1]
- 第三个是3,则需要经历[1,.]才到[3,.],前面需要

1*1*1=1
  • 前三结果=12+2+1=15
  • 最后一个即为15+1=16.

总结
- 用排列组合来解决这个问题

代码

class Solution:
    # @param {int[]} A an integer array
    # @return {long} a long integer
    def permutationIndex(self, lt):
        B=[]                #参照排序
        result=0            #初始化lt数列的顺序在字典序为0
        for i in lt:
            B.append(i)         
        B.sort()            
        for i in range(len(lt)-1): 
            j=len(B)-1      #j存放每次修改后的大小
            result=self.dp(j)*B.index(lt[i])+result
            B=B[0:B.index(lt[i])]+B[B.index(lt[i])+1:]       #修改后lt[i]的B
        return result+1     #最后一个结果+1

    def dp(self,x):          #x!=x*(x-1)*(x-2)*...*1
        if x<0:
            return 
        if x==1:
            return 1
        else:
            return x*self.dp(x-1)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值