双指针的妙用

1. 删除元素

1.1 删除指定值的元素

这里可以使用两个指针来实现,但是用两个指针也有几种方式

快慢双指针:slow和fast。其中slow来代表更新后的数组,fast用来遍历数组。

    def removeElement(self, nums, val):
        fast = 0
        slow = 0

        while fast < len(nums):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1

        return slow

对撞双指针(代码很模版,可以记下来):

    def removeElement2(self, nums, val):
        right = len(nums) - 1
        left = 0
        while left <= right:
            if (nums[left] == val) and (nums[right] != val):
                tmp = nums[left]
                nums[left] = nums[right]
                nums[right] = tmp
            if nums[left] != val:
                left = left + 1
            if nums[right] == val:
                right = right - 1
        return left

1.2 删除重复项

    def removeDuplicates(self, nums):
        j = 1
        for i in range(1, len(nums)):
            if nums[i] != nums[j - 1]:
                nums[j] = nums[i]
                j += 1
        return j

2.把元素按照奇偶数来划分

这里也可以用到对撞双指针的思想,代码如下:

    def sortArrayByParity3(self, nums):
        left, right = 0, len(nums)-1
        while left <= right:
            if nums[left] % 2 == 1 and nums[right] % 2 == 0:
                nums[left], nums[right] = nums[right], nums[left]
                # 上面的元素替换也可以用下面表示
                # tem = nums[left]
                # nums[left] = nums[right]
                # nums[right] = tem
                left += 1
                right -= 1
            if nums[left] % 2 == 0:
                left += 1
            if nums[right] % 2 == 1:
                right -= 1
        return nums

还可以用冒泡排序,但是冒泡排序时间复杂度为O(n^2),在处理大量数据的时候不占优

    # 基于冒泡排序的方法
    def sortArrayByParity2(self, nums):
        n = len(nums)
        i = 0
        while i < n:
            for j in range(0, n - 1 - i):
                if (nums[j] % 2 != 0) and (nums[j + 1] % 2 == 0):
                    nums[j], nums[j+1] = nums[j+1], nums[j]
                    # tmp = nums[j]
                    # nums[j] = nums[j + 1]
                    # nums[j + 1] = tmp
            i = i + 1
        return nums

3. 数组轮转

这里的思路是吧数组分成两半,分别反转就可以了,实现简单。注意这里使用了num[:]而不是nums,如果用了nums意思是重新定义一个名叫nums的数组

 

    def rotate(self, nums, k):
        length = len(nums)
        k %= length
        nums[:] = nums[::-1]
        nums[:k] = nums[:k][::-1]
        nums[k:] = nums[k:][::-1]

4. 数组的区间问题

如果要求数组的区间,依然可以用双指针的思想,用一个新的数组,里面放上tuple表示区间范围,最后在print出来

    def summaryRanges(self, nums):
        n = len(nums)
        res = []
        slow, fast = 0, 0
        while fast < n:
            if fast < n - 1 and nums[fast + 1] == nums[fast] + 1:
                fast += 1
            else:
                res.append((nums[slow], nums[fast]))
                slow = fast + 1
                fast = fast + 1
        # 此时res的内容如下:
        # [(0, 2), (4, 5), (7, 7)]
        print(res)
        # 转换成需要的字符串样式
        def p(x):
            slow, fast = x
            if slow == fast:
                return str(slow)
            else:
                return str(slow) + '->' + str(fast)

        return list(map(p, res))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值