算法--双指针

目录


前言

最近都在学习算法。突然想起来我这里有发布文章,都是为了巩固知识做的。所以现在我也写一篇吧。学算法3个月了,最先接触的算法就是这个双指针。很经典,也很简单。希望文章可以帮助到各位。


一、双指针是什么?

首先我们要明白,双指针是什么东西。他很简单,说白了就是两个变量。有什么用呢?他就是为了能在数组中进行查找。比如我给你一个数组nums:

复制代码
nums = [-5, -2, 0, 2, 3, 5]

现在要你在数组中找出有那两个数相加起来等于5,并返回其下标。当然说一下就是,双指针有很多种类型的。有相向的,有快慢的,有背向的等等。使用双指针的话,尽量保证数组有序。

那说了这么多,这个题目应该怎么解决呢?

我们可以先定义两个变量一个left一个right

让他们两个一个指向数组的头部,一个指向数组的尾部

python 复制代码
nums = [-5, -2, 0, 2, 3, 5]
left = 0
right = len(nums) - 1
while left < right:
    temp = nums[left] + nums[right]
    if temp > 5:
        right -= 1
    elif temp < 5:
        left += 1
    else:
        print(left, right)
        break

那,这个代码的结果就是2 5,对应的值就是0 和 5。因为这里我说只要找到就行了。所以写了break,要是题目有其他需求的,可以不写break。这个就是很经典的双指针了。很好理解吧。^V^

二、例题

15. 三数之和 - 力扣(LeetCode)

OK,现在讲一下我给的例题。我也是今天又来重做了一遍。有益于思考这个题目,可以多刷。

应该是可以直接使用的。这里我来说明一下。注释有什么问题可以问。我也没学多久,可以一起探讨学习。这里我就简单概括一下。题目是不是说要你找下标 i!=j!=k 这么三个元素。那么我们应该怎么做呢?第一,因为他的要求很宽松,所以任意三个元素都是可以的。那么直接强行遍历的话就是O(n**3)的时间复杂度。所以使用双指针是最优的解法。去除重复值可以使用到set,即哈希表,不是最优的写法,毕竟你都使用sort了。还多开一个空间。只是想到了,可以这么写。

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        if n < 3:
            return []
        if n == 3:
            return [nums] if sum(nums) == 0 else []
        ans = []
        # 如果说要使用到sort的话,时间不可避免到nlogn
        # 但是如果不使用sort的话,我的双指针就无法得到正确答案(因为他不能保证遍历到正确的数,会超时)
        # 所以必须使用sort,这样可以避免时间n**3或n**2
        nums.sort()
        # 要去除重复数,这样就可以避免数组的重复,问题
        # 也可以使用set,即哈希去记录,当然因为排序过,所以可以直接left+1跳过
        # cnt = defaultdict(int)
        # 枚举中间值,不需要预处理,因为已经使用了sort了
        for i in range(n - 2):
            # 留两个位置给另外两个数
            # 然后在里面使用双指针
            left = i + 1
            right = n - 1

            # 跳过重复的值,并进行剪枝
            # 当当前的数,加上最大的两个数都到小于0,说明没救了
            # 如果第一个数>0,后面所有数更大,不可能和为0
            if nums[i] + nums[-2] + nums[-1] < 0:
                continue
            if nums[i] > 0:
                break
            # 加上前面两个数,都大于0,说明后面还有更大的数,直接break就好了
            if nums[i] + nums[i + 1] + nums[i + 2] > 0:
                break
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            while left < right:
                temp = nums[left] + nums[right]
                if temp + nums[i] == 0:
                    ans.append([nums[left], nums[i], nums[right]])
                    while left < right and nums[left] == nums[left + 1]:
                        left += 1
                    while left < right and nums[right] == nums[right - 1]:
                        right -= 1
                    right -= 1
                    left += 1
                    continue
                if temp + nums[i] > 0:
                    right -= 1
                    continue
                if temp + nums[i] < 0:
                    left += 1
        return ans

作者:夜思红尘
链接:https://leetcode.cn/problems/3sum/solutions/3870602/xun-wei-01-by-chao-xi-7b-y4m3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

总结

OKOK,有问题来问哈。多多刷题,编程才会有所提升。加油💪!

相关推荐
人工智能训练2 小时前
OpenEnler等Linux系统中安装git工具的方法
linux·运维·服务器·git·vscode·python·ubuntu
散峰而望2 小时前
【算法竞赛】C++函数详解:从定义、调用到高级用法
c语言·开发语言·数据结构·c++·算法·github
CoderCodingNo2 小时前
【GESP】C++五级真题(贪心思想考点) luogu-B4071 [GESP202412 五级] 武器强化
开发语言·c++·算法
我有一些感想……2 小时前
An abstract way to solve Luogu P1001
c++·算法·ai·洛谷·mlp
前端小L2 小时前
双指针专题(三):去重的艺术——「三数之和」
javascript·算法·双指针与滑动窗口
智航GIS3 小时前
8.2 面向对象
开发语言·python
蹦蹦跳跳真可爱5893 小时前
Python----大模型(GPT-2模型训练加速,训练策略)
人工智能·pytorch·python·gpt·embedding
xwill*3 小时前
π∗0.6: a VLA That Learns From Experience
人工智能·pytorch·python
智者知已应修善业3 小时前
【求等差数列个数/无序获取最大最小次大次小】2024-3-8
c语言·c++·经验分享·笔记·算法