https://leetcode.com/problems/move-zeroes/#/description
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.
For example, given nums = [0, 1, 0, 3, 12]
, after calling your function, nums
should be [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.
Solution 1: traverse and swap last(but i think it is the first) 0 and last non 0.
class Solution(object): def moveZeroes(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ if len(nums) == 0: return 0 last0 = 0 for i in range(0,len(nums)): if nums[i] != 0: nums[i], nums[last0] = nums[last0], nums[i]
last0 += 1
Note:
1 This also a "two-pointer" technique problem. The time complexity is O(n), however, we actually scan the list twice.
The last0 pointer keeps track of the last 0 of the front part of the list, and nums[i] scans the last non-zero element so far. No need to think of the beginning position of the nums[i], non-zero element, because it does not impact the time compexity of the algorithm, so no need to "optimize" it.
2 last0 is the slow pointer, and it traverses when we find the last non-zero element.
Initialize last0 with 0 and begin the for loop of nums[i].
nums[i] is the fast pointer, and it traverses when it meets the non-zero element.
When it meeats the non-zero element, 1) swap last0 and nums[i] 2) advance last0. (last0 is the index of the last zero. )
3 Don't write two for loops. You know the time complexity will be O(n^2).
Write this:
last0 = 0
for num in nums:
XXXXXXXXX
last0 += 1
Here's the example.
Solution 2 : scan the whole array first and copy non 0 elements to the front of the array. Keep track of the breakpoint j. Then set elements after breakpoint j to 0.
Time Complexity: O(n), Space Complexity: O(1)
class Solution(object): def moveZeroes(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ if len(nums) == 0: return 0 j = 0 for i in range(0,len(nums)): if nums[i] != 0: nums[j] = nums[i] j += 1 for i in range(j,len(nums)): nums[i] = 0
Similar problem :
26. Remove Duplicates from Sorted Array
27. Remove Element
https://leetcode.com/problems/remove-element/#/description
Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
Example:
Given input array nums = [3,2,2,3]
, val = 3
Your function should return length = 2, with the first two elements of nums being 2.
Sol:
(similar to solution 2 for problem 283. Move Zeroes)
Scan the whole list first, store elements that do not equal to the value to the front of the original list.
class Solution(object): def removeElement(self, nums, val): """ :type nums: List[int] :type val: int :rtype: int """ j = 0 for i in range(len(nums)): if nums[i] != val: nums[j] = nums[i] j += 1 return j