You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组左旋转k次的代码逻辑问题求助:我的实现存在什么错误?

问题分析与修正

你的代码核心问题出在位置映射逻辑错误,以及交换方式不符合左旋转的元素移动规则,我们一步步拆解:

1. 位置映射公式完全错误

你提到“k=1时a[0]应映射到a[n-1]”,这个理解是对的(左旋转1次,第一个元素移到末尾),但你写的(i+n-1+k)%n完全不符合这个逻辑:

  • 当k=1,n=5,i=0时,计算得(0+5-1+1)%5 = 5%5=0,相当于交换a[0]和它自己,根本没移动元素;
  • 当k=2,i=0时,(0+5-1+2)%5=6%5=1,交换a[0]和a[1],这和左旋转需要把a[0]移到索引3的目标完全不符。

左旋转k次的正确位置映射应该是:

  • 原数组中索引为i的元素,左旋转k次后,应该出现在新数组的(i - k) % n位置(或者反过来,新数组索引j对应的原数组元素是(j + k) % n)。
    比如原数组[1,2,3,4,5],k=2:
  • 原i=0的元素1,目标位置是(0-2)%5=3;
  • 原i=1的元素2,目标位置是(1-2)%5=4;
  • 原i=2的元素3,目标位置是(2-2)%5=0,这完全符合预期结果[3,4,5,1,2]。

2. 逐个交换的逻辑会打乱元素

就算位置映射对了,你现在的循环方式(遍历每个i,交换a[i]和目标位置元素)也会出错:因为当你交换i和目标位置的元素后,后续循环到目标位置时,会把已经归位的元素又交换回去,最终结果完全混乱。

修正方案

这里给你两种常用的正确实现方式:

方式一:使用临时数组(直观易懂)

直接根据正确的映射关系构建新数组,代码简洁清晰:

def array_left_rotation(a, n, k):
    # 先处理k大于n的情况,避免无效旋转
    k = k % n
    # 新数组的前n-k个元素是原数组的k到n-1部分,后k个是原数组的0到k-1部分
    return a[k:] + a[:k]

比如输入[1,2,3,4,5],n=5,k=2,a[2:]是[3,4,5],a[:2]是[1,2],拼接后就是[3,4,5,1,2],完美符合需求。

方式二:原地修改(三次反转法,空间复杂度O(1))

如果要求不能使用额外数组,可以用经典的三次反转技巧,不需要额外空间:

  1. 反转数组的前k个元素;
  2. 反转数组的后n-k个元素;
  3. 反转整个数组。

代码实现:

def array_left_rotation(a, n, k):
    k = k % n  # 处理k大于n的情况
    
    def reverse(arr, start, end):
        while start < end:
            arr[start], arr[end] = arr[end], arr[start]
            start += 1
            end -= 1
    
    reverse(a, 0, k-1)
    reverse(a, k, n-1)
    reverse(a, 0, n-1)
    return a

测试输入[1,2,3,4,5],k=2:

  • 第一步反转前2个元素:[2,1,3,4,5]
  • 第二步反转后3个元素:[2,1,5,4,3]
  • 第三步反转整个数组:[3,4,5,1,2],得到正确结果。

进阶:原地循环交换(逻辑稍复杂)

如果想用原地交换的方式,需要找到元素的循环链(比如原位置0→3→1→4→2→0,这样一个循环链),然后在每个链内交换元素,而不是逐个遍历交换:

def array_left_rotation(a, n, k):
    k = k % n
    count = 0
    for start in range(n):
        if count >= n:
            break
        current = start
        prev_val = a[start]
        while True:
            next_idx = (current - k) % n
            if next_idx == start:
                a[current] = prev_val
                count += 1
                break
            a[current], prev_val = prev_val, a[next_idx]
            current = next_idx
            count += 1
    return a

这种方式能正确处理原地交换,但逻辑相对复杂,不如前两种直观。

内容的提问来源于stack exchange,提问作者mourinho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:35:17