三次反转和python切片 解决 旋转数组
首先声明这几种方法是借鉴Leetcode题解中[吴彦祖](https://leetcode-cn.com/problems/rotate-array/solution/san-ci-fan-zhuan-fu-yi-xie-pythonicde-jie-fa-pytho/)的解法,单纯为和我一样的freshchicken做补充思路及记录用,侵删
旋转数组问题
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入:[1,2,3,4,5,6,7]
和 k = 3 输出:[5,6,7,1,2,3,4]
三次反转
首先说说反转,如 ‘abc‘ 反转后得 ‘cba‘。三次反转的思想是将按数组索引分别将前k个元素和后k个元素反转,再将整体数组进行反转(顺序可换) 。如要实现‘abcdefg‘旋转4次,即k = 4,那么就是将数组的前k个元素‘abc‘ 和 后k个元素‘defg‘反转。反转得到 ‘cba‘ 和 ‘gfed‘。因为是基于索引原地反转,所以原数组变为‘cbagfed‘
最后将原数组整体反转 即得到4次旋转后的数组 ‘ defgabc ‘。可以看到成功的将后k个元素旋转到了数组
明白了原理下一步就是用代码将它实现出来
class Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ # 给定的K为非负数,可能超出数组长度,先计算出实际旋转次数k n = len(nums) k %= n # 定义反转函数 def switch(a, b): while (a<b): # 从两头往中间交换 nums[a], nums[b] = nums[b], nums[a] a += 1 b -= 1 # 三次反转 switch(0, n-k-1) # 反转前k个元素 switch(n-k, n-1) # 反转后k个元素 switch(0, n-1) # 反转整体
# 当然利用python的切片特性我们可以更简洁的实现反转 class Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ k %= len(nums) nums[:] = nums[:][::-1] nums[:k] = nums[:k][::-1] nums[k:] = nums[k:][::-1]
前面说过。旋转数组其实可以看为将后k个元素移动到前面来。那不考虑原地算法的前提下用python其实可以写出更简洁的代码,虽然不符合本题正统做法,但可做扩展用。
class Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ k %= len(nums) nums[:] = nums[k:] + nums[:k]
两行代码完事hh,可能这就是python的魅力吧。
原文地址:https://www.cnblogs.com/Aquish/p/12642787.html
时间: 2024-11-09 19:21:00