数组零元素移至头部算法问题:现有代码非零元素被异常排序求修复方案
问题根因
你当前的正向遍历交换逻辑,每次遇到0就和左边界位置做交换,会把原本排在前面的非零元素交换到靠后的位置,直接破坏了非零元素的原有相对顺序。以你的示例输入为例:第一个0出现在索引2的位置,此时交换索引2和边界0的元素,原本排在首位的4就被换到了索引2的位置,后续遍历过程中4还会被不断往后交换,最终出现在非零元素的末尾,和要求不符。
修正实现
这里提供两种实现方案:
方案1:额外数组拼接(逻辑最简单,无副作用)
直接两次遍历原数组,先收集所有0元素,再按顺序收集所有非0元素,合并后就是符合要求的结果,天然保证非零元素的相对顺序:
func moveZerosTotheFront(arrays:[Int] )->[Int] { var zeros = [Int]() var nonZeros = [Int]() for num in arrays { if num == 0 { zeros.append(num) } else { nonZeros.append(num) } } return zeros + nonZeros }
方案2:原地修改(空间复杂度O(1))
如果要求不能申请额外数组空间,可以改成倒序遍历实现:
- 边界指针从数组末尾开始往前移动
- 从后往前遍历数组,遇到非零元素就和当前边界位置交换,边界同步前移
- 遍历完成后所有0会自然留在数组头部,非零元素保持原有相对顺序
func moveZerosTotheFront(arrays:[Int] )->[Int] { var result = arrays var boundary = arrays.count - 1 // 倒序遍历 for index in stride(from: arrays.count - 1, through: 0, by: -1) { if result[index] != 0 { result.swapAt(index, boundary) boundary -= 1 } } return result }
验证结果
以你的示例输入[4,2,0,1,0,3,0]测试,两种方案输出均为[0,0,0,4,2,1,3],符合非零元素保持原有相对顺序的要求。
内容的提问来源于stack exchange,提问作者Retro Boomin
相关产品推荐
相关产品推荐

