同向双指针

两个指针同向运动,用两个变量,一个变量记录当写指针的位置(fast index), 一个变量记录隔板位置(slow index).

  • 性质1. slow左边是处理好的元素,当先指针fast右边是未处理的元素,两个指针之间的区域是无用的元素/每次只要分析当前元素性质是否要加入或者移动slow就可以!
  • 性质2. 用快慢指针,同向而行,处理完毕之后,return的结果中,每个integer/char的相对位置不变!

1 Element Removal 删除元素

  • 删除或者保留具有某些性质的元素

27. Remove Element

class Solution(object):
    def removeElement(self, nums, val):
        if not nums: return 0
        slow = 0
        for i in xrange(len(nums)):
            if nums[i] != val:
                nums[slow] = nums[i]
                slow += 1
        return slow

26. Remove Duplicates from Sorted Array

  • 双指针,一个fast指针作为遍历指针,一个slow作为“有效值”指针
    • fast: all elements to the left hand side of slow (excluding slow) are the final results to return
    • slow: current index
class Solution(object):
    def removeDuplicates(self, nums):
        if not nums: return 0
        slow = 1 # slow为下一个“有效值”该放的位置
        for i in xrange(1, len(nums)):
            # 和前一个元素不相等,所以为“有效值”
            if nums[i] != nums[i-1]: # nums[i] != nums[slow-1] 也可以!
                nums[slow] = nums[i]
                slow += 1
        return slow
  • Follow up

    • 最多保留一个相同元素 -> 保留两个? LeetCode80
    • 最多保留k个相同元素?
    • 一个都不保留,删除所有重复元素!!!
  • slow : all elements to the left hand side of slow (excluding slow) are the final results to return.

  • fast1: current index.
  • fast2: 探路指针指向重复的最后一个
    • 根据fast1和fast2的距离判断重复

80. Remove Duplicates from Sorted Array II

  • slow : all elements to the left hand side of slow (excluding slow) are the final results to return.
  • fast : current index
class Solution(object):
    def removeDuplicates(self, nums):
        if len(nums) <= 2:
            return len(nums)

        slow = 2
        for i in xrange(2, len(nums)):
            # Key Point:遍历的当前位置和slow-2的位置比
            if nums[i] != nums[slow-2]:
                nums[slow] = nums[i]
                slow += 1
        return slow

283. Move Zeroes

  • move all 0's to the end of it while maintaining the relative order of the non-zero elements.
  • 由于要保证相对顺序不变,所以只能用同向双指针!
    • slow:all elements to the left hand side of slow (excluding slow) must be non zero.
    • fast: current index
    • [slow, fast]: unexplored subarray
class Solution(object):
    def moveZeroes(self, nums):
        non = 0
        for i in xrange(len(nums)):
            if nums[i] != 0:
                nums[non], nums[i] = nums[i], nums[non]
                non += 1

    def moveZeroes1(self, nums):
        slow = 0
        for i in xrange(len(nums)):
            if nums[i] != 0:
                nums[slow] = nums[i]
                slow += 1
        while slow <= len(nums)-1:
            nums[slow] = 0
            slow += 1
  • What if we do not need to maintain the relative order of the elsements ?
    • 相向双指针
class Solution(object):
    def moveZeroes(self, nums):
        left = 0
        right = len(nums) - 1
        while left <= right:
            if nums[left] != 0:
                left += 1
            elif nums[right] == 0:
                right -= 1
            else:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
                right -= 1
        return left

results matching ""

    No results matching ""