题目
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思考
- 解法一:带尾指针的单向循环链表
将字符串创建成单向循环链表,因此改变头指针self,__head,即可完成字符串左移的效果。 - 解法二:字符串操作
通过取余操作,将循环左移的位数变成字符串切片的偏移量。
d i f f = d i v m o d ( n , l e n ( s ) ) [ 1 ] diff = divmod(n,len(s))[1] diff=divmod(n,len(s))[1]
重新将字符串拼接即可 - 算法比较
- 算法二空间复杂度为O(n),但是算法一也需要将字符串全部创建成链表,链表不仅需要存val还需要存储指针。这样看来,算法二更优。
代码
- 解法一
# -*- coding:utf-8 -*-
class Node():
def __init__(self,val):
self.val = val
self.next = None
class MyList(): #尾指针指向头节点的单向链表
def __init__(self):
self.__head = None
def add(self,item):
"""尾插元素"""
if self.__head is None:
node = Node(item)
self.__head = node
node.next = node
else:
cur = self.__head
node = Node(item)
while cur.next != self.__head: #退出循环时,cur指针指向尾节点
cur = cur.next
cur.next = node
node.next = self.__head
def travel(self):
"""遍历"""
if self.__head is None:
return
cur = self.__head
res = ""
while cur.next != self.__head:
res += cur.val
cur = cur.next
res += cur.val
return res
def leftRotate(self,n):
count = 0
cur = self.__head
while count < n%len(s): #退出循环时,cur指针指向新的头节点
cur = cur.next
count += 1
self.__head = cur
return self.travel()
class Solution:
def LeftRotateString1(self, s, n):
"""带尾指针的单向链表"""
if not s:
return ''
myList = MyList()
for item in s:
myList.add(item)
return myList.leftRotate(n)
- 解法二
def LeftRotateString2(self, s, n):
"""字符串操作"""
if not s: #空字符串不为None?
return ''
diff = n%len(s)
return s[diff:]+s[:diff] #字符串拼接与切片