【问题标题】:How to shift items in an array by a "K" number of times?如何将数组中的项目移动“K”次?
【发布时间】:2022-01-22 14:10:16
【问题描述】:

将给定数组中的项目移动一定次数,如下例所示;

array = [1, 2 ,3 , 4, 5, 6]
k1 = 2
k2 = -3
k3 = 20

test1:
cirShift(array, k1)
Result: [5, 6, 1, 2, 3, 4]

test2:
cirShift(array, k2)
Result: [4, 5, 6, 1, 2, 3]

test3:
cirShift(array, k3)
Result: [5, 6, 1, 2, 3, 4]

我已经使用下面的方法实现了k位置的右旋转列表;

def rightRotateByOne(A):
    Fin= A[-1]
    for i in reversed(range(len(A) - 1)):
        A[i + 1] = A[i]
    A[0] = Fin
 
def rightRotate(A, k):
    if k < 0 or k >= len(A):
        return
    for i in range(k):
        rightRotateByOne(A)
 
if __name__ == '__main__':
    A = [1, 2, 3, 4, 5, 6, 7]
    k = 3
    rightRotate(A, k)
    print(A)

截至目前,能够获得test1的结果,但想实现test2test3

【问题讨论】:

  • rightRotate(A, k) 应该产生与rightRotate(A, k % len(A)) 相同的输出。您可以在# base case: invalid input 行之前添加k %= len(A)
  • 其实上面的评论已经解决了test2和test3
  • 这能回答你的问题吗? Python list rotation

标签: python arrays list


【解决方案1】:

更简单的是,给定边界,将数组分成两半,交换并粘合回来:

def cirShift(a, shift):
    if not shift or not a:
        return a
    return a[-shift%len(a):] + a[:-shift%len(a)]

感谢@KellyBundy,一个短路单线:

def cirShift(a, shift):
    return a and a[-shift%len(a):] + a[:-shift%len(a)]        

【讨论】:

  • 它也会失败,例如,6 元素列表和 -83 班次。
  • @KellyBundy 感谢您指出这一点。修复很简单,更新了答案
  • @KellyBundy 也解决了这个问题;不幸的是,这是一个非常丑陋的单线或额外的if
  • 可以在正常结果之前插入a and。但是,如果有一天您决定事先只计算一次索引,if 可能会更好。
  • 顺便说一句,我也忘记了空箱,看到它在其中一个问题中指出,这个问题当然已经存在。
【解决方案2】:

我认为这个问题可能是一个自学的练习('how to do X using just python'),所以我的回答是辅助性的,但你总是可以使用np.roll()

#test 1
import numpy as np
a = [1, 2 ,3, 4, 5, 6]
np.roll(a, 2)

给出输出

[5, 6, 1, 2, 3, 4]

#test 2
np.roll(a, -2)

给出输出

[3, 4, 5, 6, 1, 2]

即使你给出一个大于数组大小的数字,它也会处理溢出:

#test 3
np.roll(a, 10)

给出输出

[3, 4, 5, 6, 1, 2]

滚动也适用于多维数组和跨指定轴,非常简洁。

【讨论】:

    【解决方案3】:
    def shift(l, shift_t):
     r = [*l]
     for n in range(abs(shift_t)):
      if shift_t < 0:
       r = r[1:] + [r[0]]
      else:
       r = [r[-1]] + r[:-1]
     return r
    

    关键是从列表中取出一项并将其放在另一侧,这基本上就是移位所做的一切。如果移负,则将第一个放在末尾,如果移正,则将最后一个放在开头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-09
      • 2014-08-07
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多