1. 题目描述
给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数。
示例1:
输入:[1, 2, 3, 4, 5, 6, 7] 和 k = 3 输出:[5, 6, 7, 1, 2, 3, 4] |
示例2:
输入:[-1, -100, 3, 99] 和 k = 2 输出:[3, 99, -1, -100] |
说明:
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为O(1)的原地算法。
2. 使用列表操作方法实现
首先想到的是直接列表的方法,尾部的追加可以使用append或者extend方法,这里涉及多个数值所以采用extend方法。对于前面的值弹出,可以使用pop方法,但是会耽误时间,在这里可以使用del方法,直接删掉前面的部分。经测试,为“通过”。
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
nLen = len(nums)
idx = k % nLen # 对k求余保证始终在长度范围内
nums.extend(nums[:nLen-idx])
del nums[:nLen-idx]
3. 使用切片的重组功能
考虑到切片的功能,可以先将数组分为前半部分和后半部分,然后再将两者反着拼接起来。经测试,显示“通过”。
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
idx = k % len(nums)
nums[:] = nums[-idx:] + nums[:-idx] # 使用负索引省去加减操作
4. 使用反转的规律
仍然是使用切片分成前半部分和后半部分,先分别对前、后半部分使用函数reversed就地反转,然后对整个序列再次使用函数reversed就地反转即可。经测试,显示“通过”。
举例:
初始时,序列为[1, 2, 3, 4, 5, 6, 7] 和 k = 3 |
前半部分 后半部分 初始状态: [1, 2, 3, 4 ] [5, 6, 7] 就地反转后: [4, 3, 2, 1] [7, 6, 5] |
序列为:[4, 3, 2, 1, 7, 6, 5] |
再次反转后:[5, 6, 7, 1, 2, 3, 4] |
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
idx = k % len(nums)
nums[:-idx] = reversed(nums[:-idx])
nums[-idx:] = reversed(nums[-idx:])
nums[:] = reversed(nums[:])
(最近更新:2018年10月28日)