C#求解LeetCode189旋转数组 赋值后原数组未修改问题
题目描述
对应题目
给定一个数组,将数组向右旋转k步,其中k为非负整数。
示例1
Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4]
问题复现
提交的实现代码
public class Solution { public void Rotate(int[] nums, int k) { List<int> list = nums.ToList(); for (int i = 0; i < k; i ++) { int first = nums[0]; list.RemoveAt(0); list.Add(first); } nums = list.ToArray(); } }
提交返回错误
Wrong Answer Runtime: 156 ms Your input [1,2,3,4,5,6,7] 3 Output [1,2,3,4,5,6,7] Expected [5,6,7,1,2,3,4]
错误原因
你的代码一共存在3个问题,直接导致结果不符合预期:
- 赋值不生效的核心原因:C#方法的参数默认是值传递,哪怕是数组这种引用类型,你在方法内部给形参
nums重新赋值,只会修改方法内部这个局部变量的指向,完全不会影响方法外部传入的原数组,判题机读取原数组时拿到的自然还是初始值。 - 循环逻辑完全无效:循环里你每次取的是从未被修改过的原数组的第一个元素
nums[0](在这个测试用例里永远是1),从list里删掉第一个元素再把1加回去,不管循环多少次list的内容都不会变化。 - 旋转方向逻辑错误:就算你修正了取值问题,每次把列表头部元素移到尾部是左旋转的实现,题目要求的右旋转逻辑是每次把尾部元素移到头部。另外你没有处理k大于数组长度的情况,比如数组长度为7、k为10时,实际只需要旋转3步,多余的循环全是无效计算。
修正方案
- 不要直接给形参
nums赋值,计算完成后要把结果逐个拷贝到原nums数组的对应位置,才能真正修改原数组内容 - 可以直接用切片拼接的方式实现旋转,避免逐次移动元素的低效率问题
- 提前对k取模,过滤掉整轮旋转的无效计算
修正后的参考代码:
public class Solution { public void Rotate(int[] nums, int k) { int len = nums.Length; k = k % len; // 右旋转k步等价于:后k个元素放到最前面,拼接前len-k个元素 int[] res = nums.Skip(len - k).Take(k).Concat(nums.Take(len - k)).ToArray(); // 拷贝结果到原数组 for (int i = 0; i < len; i++) { nums[i] = res[i]; } } }
内容的提问来源于stack exchange,提问作者Liu_064
相关产品推荐
相关产品推荐

