内功修炼——接触双指针

一、双指针简介

  1. 双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。
  2. 双指针可以从不同的方向向中间逼近也可以朝着同一个方向遍历

变异的双指针

有时候,我们能很容易看出来题目是双指针类型的变异,但是直接使用双指针的话又不行。就会不知觉的想到,难道要用三指针?四指针?(饶饶我吧,四指针我也不会啊)。所以这时,我们可以在双指针的基础上使用其他的数据结构,例如说哈希表、数组等。或者是多加一层循环

二、例题

1. leetcode 15 三数之和

题解思路参考

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,
使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。		
注意:答案中不可以包含重复的三元组。

排序 + 双指针
本题的难点在于如何去除重复解。

算法流程:
特判,对于数组长度 nn,如果数组为 nullnull 或者数组长度小于 33,返回 [][]。
对数组进行排序。
遍历排序后数组:
	若 nums[i]>0nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 00,直接返回结果。
	对于重复元素:跳过,避免出现重复解
	令左指针 L=i+1L=i+1,右指针 R=n-1R=n−1,当 L<RL<R 时,执行循环:
	当 nums[i]+nums[L]+nums[R]== 0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解
		若和大于 0,说明 nums[R] 太大,R 左移
		若和小于 0,说明 nums[L] 太小,L 右移

作者:zhu_shi_fu
链接:https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. (变异双指针) leetcode 18 四数之和

  • 题目:
    给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。(来源leetcode)
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        if(not nums or len(nums) < 4):
            return []
        n = len(nums)

        # 结果
        res = []

        # 排序
        nums.sort()

        for i in range(n-3):
            # 加快判断,获取最小值
            if(target < nums[i]+nums[i+1]+nums[i+2]+nums[i+3]):
                break
            # 加快判断,获取最大值
            if(target > nums[i]+nums[n-1]+nums[n-2]+nums[n-3]):
                continue

            # 避免重复
            if(i > 0 and nums[i] == nums[i-1]):
                    continue
           
            for j in range(i+1, n-2):
                # 加快判断,获取最小值
                if(target < nums[i]+nums[j]+nums[j+1]+nums[j+2]):
                    break
                # 加快判断,获取最大值
                if(target > nums[i]+nums[j]+nums[n-1]+nums[n-2]):
                    continue
                
                # 避免重复
                if(j > i+1 and nums[j] == nums[j-1]):
                    continue

                L = j + 1
                R = n - 1
                while(L < R):
                    tmp = nums[i]+nums[j]+nums[L]+nums[R]
                    if(tmp > target):
                        R = R- 1
                    elif(tmp < target):
                        L = L + 1
                    else:
                        res.append([nums[i],nums[j],nums[L],nums[R]])
                        # 防止重复
                        while(L < R and nums[L] == nums[L+1]):
                            L = L + 1
                        
                        while(L < R and nums[R] == nums[R-1]):
                            R = R - 1

                        L = L + 1
                        R = R - 1 
        
        return res

3. 链表是否有环、环的节点(考虑到速度差)等

(后续有时间了再进行补充)

写在最后

如果觉得本文对你有帮助的话,可以为我点个赞哈,你的关注和支持是我坚持下去最大的鼓励。
新手上路,对文章有什么建议和意见,也欢迎留言告诉我,期待你的回馈。

发布了13 篇原创文章 · 获赞 13 · 访问量 636

猜你喜欢

转载自blog.csdn.net/coding_sleep/article/details/105299231
今日推荐