面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

下面我们一起来思考这道移动元素的题目,不得不说,这类题目在面试中,是比较常见的一种题目类型,让我们来头脑风暴下吧。

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

头脑风暴!!

题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

示例

<code>输入: [0,1,0,3,12]
输出: [1,3,12,0,0]/<code>

题解

这类题目,属于比较常见的元素交换题目。

最主要的难点,应该就是在原数组上进行操作,不使用创建新的数组和集合,而且尽量只进行一次数组的遍历。

题目要求的是,移动所有0的元素到数组末尾,而其他元素的相对元素要保持不变,其实可以相当于我们将0作为一个中间点,将非0的数字移动到中间点的左边,等于0的移动到中间点的右边。

听起来是不是有点熟悉,其实就是我们的快速排序的一个思想,中间点。这里就不扩展说了,等之后有做到排序题目时我们再来说道说道。

那么我们便定义两个指针i和j,当nums[i]不等于0的时候,我们将nums[i]交换到左边,等于0的交换到右边。

  • 代码
<code>public void moveZeroes(int[] nums) {
int j = 0;
for(int i=0;i<nums.length> if(nums[i]!=0){
int temp = nums[j];
nums[j++] = nums[i];
nums[i] = temp;
}
}
}/<nums.length>/<code>
  • 图解

举个例子[1,2,0,3,4]

1、一开始i=0,j=0,此时判断到nums[i]不等于0,交换i和j的数组元素(其实相当于没换),之后递增i和j

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

2、之后i=1,j=1,此时步骤与第1步一样,递增i和j

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

3、之后i=2,j=2,此时判断到nums[i]=0,将继续遍历,递增i,而指针j不动,即得到了i=3,j=2,此时指针j由于没有移动将指向0元素,而指针i移动到下个元素

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

4、此时判断到nums[i]不等于0,交换i和j指针所指向元素,也就是交换不等于0的到左边,等于0的交换到右边,同时递增i和j

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)

5、此时i指向元素4,j指向元素0,nums[i]不等于0,同样进行交换,至此交换结束,得到最终结果

面试可不能被这种算法题打倒:原地移动元素(附代码和图解)


分享到:


相關文章: