[leetcode] Move Zeroes
Posted Lin.B
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[leetcode] Move Zeroes相关的知识,希望对你有一定的参考价值。
Given an array nums
, write a function to move all 0
‘s to the end of it while maintaining the relative order of the non-zero elements.
Example:
Input:[0,1,0,3,12]
Output:[1,3,12,0,0]
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
class Solution { public void moveZeroes(int[] nums) { for ( int left = 0 ; left < nums.length - 1 ; left++ ) { if (nums[left] == 0) { int right = left + 1; while (right < nums.length) { if (nums[right] != 0) { swap(nums, left, right); break; } right++; } } } } private void swap(int[] nums, int left, int right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } }
运行时间17ms,击败9.00%的提交。显然还是有很大的提升空间的。
第三个思路:我认为上面用Two Pointers的思路是正确的,为什么这么多时间浪费了呢,分析一下原因:right指针做了很多重复性的工作。例如[1,0,0,3,12]中,left指向第一个0,和left指向第2个0,right指针动作都是相同(类似)的,如果连续有很多个0,那么right指针就会非常浪费时间。因此用Two Pointer的思路来了:right指针总是指向第一个非0的元素,left指针总是指向第一个0元素。然后交换两个位置。代码如下:
1 class Solution { 2 public void moveZeroes(int[] nums) { 3 int left = 0; 4 int right = 0; 5 while ( right < nums.length ){ 6 while ( nums[right] == 0 && right < nums.length - 1 ) right++; 7 if ( nums[left] == 0 ) swap(nums,left,right); 8 left++; 9 right++; 10 } 11 } 12 private void swap(int[] nums, int left, int right) { 13 int temp = nums[left]; 14 nums[left] = nums[right]; 15 nums[right] = temp; 16 } 17 }
运行时间1ms,击败100%的提交。这里一定要注意第6行的边界条件。卡在这错了好几个。。。right的值在变化的过程中一定要满足6行的条件。
第二种方法才是Two Pointers的精髓啊!!!两个指针一定要是独立的,第一个方法虽然也是两个指针但是时间复杂度是O(nlogn),而且right指针是依附于left的。日渐感受到双指针的优势。
以上是关于[leetcode] Move Zeroes的主要内容,如果未能解决你的问题,请参考以下文章