C# 将数组指定值移至末尾 连续匹配元素移位异常如何修复
问题根因
现有代码的缺陷来自遍历逻辑的疏漏:当你在位置i匹配到目标值并执行左移操作后,原位置i+1的元素会被移动到i的位置,此时如果直接执行i++,就会跳过对新移动到i位置元素的校验,连续出现的目标值就会被漏处理。
方案1:最小修改现有逻辑
只需要调整遍历的自增规则,匹配到目标值时不执行自增,只有未匹配时才向后移动指针即可解决问题:
static void Main(string[] args) { int[] source = new int[] { 1, int.MinValue, int.MinValue, int.MaxValue, int.MinValue, -1, -3, -9, 1 }; int value = int.MinValue; // 替换原有for循环,使用while控制指针移动 int i = 0; // 已经移到末尾的目标值不需要重复遍历,减少不必要的操作 int processedCount = 0; while (i < source.Length - processedCount) { if (source[i] == value) { LeftShiftArray(source, i); processedCount++; // 匹配到目标值时不移动i,继续校验当前位置的新元素 } else { // 未匹配时才向后移动指针 i++; } } for (int j = 0; j < source.Length; j++) { Console.WriteLine(source[j]); } } public static void LeftShiftArray(int[] source, int i) { var temp1 = source[i]; for (var j = i; j < source.Length - 1; j++) { source[j] = source[j + 1]; } source[source.Length - 1] = temp1; }
方案2:更高性能的双指针实现
原有移位方案的时间复杂度为O(n²),使用双指针法可以将时间复杂度降到O(n),同时完全避免索引越界、连续值漏处理等问题:
static void MoveTargetToEnd(int[] source, int target) { // 慢指针:记录下一个非目标值的存放位置 int slow = 0; // 快指针:遍历整个数组 for (int fast = 0; fast < source.Length; fast++) { if (source[fast] != target) { source[slow] = source[fast]; slow++; } } // 慢指针之后的所有位置统一赋值为目标值 for (int i = slow; i < source.Length; i++) { source[i] = target; } }
直接调用该方法替换原有遍历+移位的逻辑即可,所有测试用例均可正常通过。
内容的提问来源于stack exchange,提问作者Linascts
相关产品推荐
相关产品推荐

