Leetcode中移动零(https://leetcode-cn.com/problems/move-zeroes/)和快速排序的最初版本,本质上都可以使用区间来简化代码。
首先以移动零为例,假设两个循环变量分别为 j j j和 i i i(假设 j < = i j<=i j<=i),则 [ 0 , . . . , j ] [0,...,j] [0,...,j]中均为非零元素(区间1),而 [ j + 1 , . . . , i − 1 ] [j+1,...,i-1] [j+1,...,i−1]均为零(区间2)。其中i是从最开始滑到最后一个元素的。
由于区间1和区间2最开始都没有元素,则两个区间应该为空,所以得到 j = − 1 j=-1 j=−1以及 i = 0 i=0 i=0。假设nums[i]为0,则什么都不要做,假设nums[i]不为0,则需要进行交换。具体如代码:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# [0, j] not zero, [j+1, i-1] all zero
j = -1
for i in range(0, len(nums)):
if nums[i] != 0:
nums[i], nums[j+1] = nums[j+1], nums[i]
j += 1
接着以最简单的快速排序中partition函数为例。
def partition(nums, l, r):
# [l+1,...,j] < v, [j+1,...,i-1] > v
v = nums[l]
j = l
for i in range(l+1, r+1):
if nums[i] < v:
nums[i], nums[j+1] = nums[j+1], nums[i]
j += 1
nums[l], nums[j] = nums[j], nums[l]
return j
如果是两个区间,则 j j j从-1开始,如果是单个区间,则 j j j从0或者其他正整数开始。(更准确的解释是说,如果已经有基准元素的话, j j j从-1开始,如果需要基准元素,则需要向前走N步,得到基准元素,则 j j j从0或者其他正整数开始)。
- 删除排序数组中的重复项
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# [0,...j] non duplicates i
j = 0
for i in range(0, len(nums)):
if nums[j] != nums[i]:
nums[j+1] = nums[i]
j += 1
return j + 1
- 移除元素
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
#[0,...j] != val, [j+1,...i-1] == val
j = -1
for i in range(0, len(nums)):
if nums[i] != val:
nums[i], nums[j+1] = nums[j+1], nums[i]
j += 1
return j + 1
- 删除排序数组中的重复项
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# [0,...j] non duplicates i
if len(nums) == 0:
return 0
j = 0
for i in range(0, len(nums)):
if nums[j] != nums[i]:
nums[j+1] = nums[i]
j += 1
return j + 1
- 删除排序数组中的重复项 II
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# [0,...j] non duplicates
if len(nums) <=1:
return len(nums)
j = 1
for i in range(2, len(nums)):
if not (nums[i] == nums[j] and nums[i] == nums[j-1]):
nums[j+1] = nums[i]
j += 1
return j + 1
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# [0, zeros] 0, [zeros+1, i-1] 1, [two, n-1] 2
zeros = -1
i = 0
two = len(nums)
while i < two:
if nums[i] == 0:
nums[zeros+1], nums[i] = nums[i], nums[zeros+1]
zeros += 1
i += 1
elif nums[i] == 1:
i += 1
else:
nums[two-1], nums[i] = nums[i], nums[two-1]
two -= 1
多个区间的问题怎么解决呢?
https://bohenan.gitbooks.io/leetcode/lai-rainbow-sort-iii.html
http://sgq626.blogspot.com/2015/07/leetcode-75-sort-colors-sort-color-ii.html