移动零
思路——双指针
如果可以开辟额外的空间,那这题十分好做。我们开辟和nums
同样大小的空间,将遍历数组,将非零元素从头放置,将零从后往前放置,这样就可以将所有的零放到后面,同时保证非零元素的相对顺序。
如图,对于数组[1,0,0,4,1,2,0]
:
但是这一题要求我们不能额外开辟空间,即要求我们的空间复杂度为O(1)
,那我们就要思考用双指针的方法了。
- 我们定义指针
left
用来指向已经处理好的序列末尾,指针right
指向还未处理好的序列开头 right
向后开始遍历数组,当right
指向非零元素时,就交换left
和right
指向的元素,同时left
右移- 最终就可以得到答案
如图:
实现代码
//由于形参的改变不影响实参,因此要实现真正的交换要传地址 void Swap(int *num1, int *num2) { int temp = *num1; *num1 = *num2; *num2 = temp; } void moveZeroes(int *nums, int numsSize) { int left = 0, right = 0; while (right < numsSize) { //right指向非零元素就交换right和left的数据,同时left右移 if (nums[right] != 0) { Swap(nums + left, nums + right); left++; } //right向右遍历数组 right++; } }