题目描述:
给定一个字符串和要旋转的次数/位数, 请给出左旋之后的字符串;
比如:输入:"abcXXzDEF", 3
输出: "XXzDEFabc"
所谓左旋,是将串最左边的值,逆时针旋转到最右边;
所谓右旋,是将串最右边的值,顺时针旋转到最左边;
实现思路:
看了好几种实现方式,觉得下面这种思路是最容易理解的,学习后,记录下来:
1、我们会发现对于上面长度为9个字符串,左旋一次后结果是: bcXXzDEFa ; 左旋两次后的结果是: cXXzDEFab ;依次类推,左旋9次后:又变成了abcXXzDEF;
所以,我们理解,旋转9次的结果,同旋转0次的结果一样;而旋转10次的结果,同旋转1次的结果一样; 所有有: 旋转n次的结果,同旋转 n%len(s) 的结果是一样的;
2、我们发现,对字符串 abcXXzDEF 左旋多少次,其结果都是 『abcXXzDEFabcXXzDEF』的子串,也就是将串拼接起来;
此时,左旋一次,就表示对拼接后的串,从第1位(默认从第0位开始)开始取,取长度为len(s); 由上面分析,那么左旋10次的结果通过旋转1次的结果一样;
所以,旋转n次的结果,就是从第n%len(s) 开始取, 取len(s)长度的子串,返回即可;
代码实现:
class Soution: def LeftRoateString(self, s, n): # 首先依然是,先对异常情况的处理 if (s == ""): return "" else: len_s = len(s) s = s + s n = n % len_s return s[n:n+len_s]
扩展学习:
1、如果是右旋,应该怎么实现呢?
思路: 同样的道理,左旋是将最左边的字符放到最右边; 右旋则是将最右边的串依次放到最左边; 同样的逻辑,将两个串拼接起来,旋转n次同旋转n%len(s)次结果一样; 与左旋不同的是,输出的子串不同;
比如,串"abcXXzDEF",右旋3位,期待结果为『DEFabcXXz』; 拼接之后是『abcXXzDEFabcXXzDEF』,那么想要输出预知的子串,就需要从总串中,从正数第6(9-3)开始 输出 输出长度为9;
也就是下面的,从 『len_s - n 』(9-3)开始输出,输出长度为len_s, 那么就是 输出到『len_s - n + len_s 』
class Solution: def RightRoateString(self, s, n): if (s == ""): return "" else: len_s = len(s) s = s + s return s[len_s-n:len_s-n+len_s]
2、Python的切片操作:
使用Python解决问题时,经常会遇到从某个对象中抽取特定部分的需求,而切片操作就是专门实现这一目标的有利武器;切片操作的基本使用语法是:
object[start_index:end_index:step] 1)object:是可以进行切片操作的数据类型,常用的 list(列表)、tuple(元组)、string(字符串)等可以迭代的对象,都可以进行切片操作; 而且,切片操作后返回的结果与切片对象类型一致; 2)step: 正负值均可,该值的绝对值表示切片的步长; 正值表示从左到右取值,步长为|step|; 负值表示从右到左取值,步长也为|step|; 如果没有注明该值,默认为1; 3)start_index:表示切片开始的索引; 如果step为正值,则start_index从左边为起点,统计的值包括该索引本身,也就是 <= start_index;默认从0开始; 如果step为负值,则start_index从右边为起点,统计的值包括该索引本身,也就是 <= start_index; 默认从-1开始; 4)end_index: 表示切片的结束索引;具体终点在左边还是右边,由step决定; 这里的统计的值不包括该索引本身,也就是 > end_index; 5)所以,可以理解切片的结果 应该是 >=start_index and < end_index 6)处理逻辑为:先看step,确定方向,再看start_index 确定起点,最后看end_index 确定终点; 7)如果切片返回的结果为非空的可切片对象,则支持连续切片操作;下面是举例子:
对列表的切片举例,定义 list_a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1、print list_a[2:5:1] 输出结果为:[2,3,4] 理解: 正向取值,step为1; 从下标为2的位置开始(包括下标为2的值),取值到 下标为5的位置结束(不包括下标为5的值); 2、start_index 和end_index缺失,只有step时: 如果start_index缺失,默认从0 或者 -1 开始; 如果end_index缺失,默认到列表的最后一个,或者第一个; 1)print list_a[::2] 输出结果为:[0, 2, 4, 6, 8] 理解:正向取值,step为2; 开始下标和结束下标都为空,则选取默认值, 从0开始,到列表最后;所以,上述切片操作的就是获取列表中所有偶数; 2) print list_a[::-2] 输出结果为: [9, 7, 5, 3, 1] 理解: 反向取值,step为2, 开始下标和结束下标都为空,则选取默认值,从-1开始,到列表的最开始位置; 所以,上述切片操作就是逆向输出列表中所有的奇数; 3)print list_a[:6:-2] 输出结果为:[9,7] 理解: 反向取值,step 为2; 开始下标缺失,默认是-1; 结束下标是6(但是取值不包括6);所以取值范围是[7,8,9],从9开始step为2,也就是[9,7] 4)print list_a[5::-2] 输出结果为:【5, 3, 1】 理解: 反向取值,step 为2; 开始下标位5(取值包括该5); 结束下标缺失,默认到列表的最后一个,因为是反向取值的最后一个,所以是列表的起点位置; 所以,取值范围是[0,1,2,3,4,5] 从5开始step 是2,也就是[5,3,1] 3、切取单个值: print list_a[6] 输出结果为:6 理解: 没有:的情况下,默认按照下标开始取值;下标从0开始,从左到右; 4、一些错误的使用: 1)print list_a[1:6:-1] 输出结果为:[] 理解: step 为-1,表示反向取值; 但是start_index=1, end_index=6 又表示正向取值,两者矛盾,所以输出为空; 2)print list_a[-1:-6:1] 输出结果为:step 为 1,表示正向取值; 但是start_index=-1,end_index=-6,又表示从右到左反向取值,两者矛盾,所以输出结果为空;
对字符串的切片举例: 对字符串的切片操作语法同上面一样,这里只是给一个字符串切片的例子; 题目:给定一个字符串,将其首字母改为大写后返回; 比如: 输入:hello; 输出:Hello;
Class Soultion: def func(self, s): if (s == ""): return "" else: return s[0].upper() + s[1:] test = Soultion() s = input("请输入一个单词: ") print("转换后的单词是:" + test.func(s))