首页 > 编程语言 >LeetCode算法—双指针

LeetCode算法—双指针

时间:2024-09-10 22:13:44浏览次数:7  
标签:right nums 元素 fast 算法 指针 LeetCode left

一:普通双指针

1、题目1:两数求和-1

(1)方法1:普通双指针

思路:定义两个指针;第一个指针放在数组的首位;第二个指针放在下一个元素的位置;然后遍历这个;如果两个元素的和为目标值就返回对对应的下标和索引值!

def fuc(nums,target):
    for i in range(len(nums)):
        for j in range(i+1,len(nums)):
            if nums[i]+nums[j]==target:
                retrun [i,j]
     return ""

(2)方法2:对撞双指针

思路:让第一个指针指向第一个元素;第二个指针指向第二个元素;然后将数组排列为有序数组;核心:如何和小于目标值的话说明最小的值太小了;第一个指针需要左移;如果和大于目标值的话说明最大的值太大了;第二个指针需要右移;符合条件使用index方法发返回未排序之前元素对应的下标索引!

def func(nums,target):
    i,j=0,len(nums)-1#让i指向第一个元素;j指向最后一个元素
    sorted_nums=sorted(nums)#将数组排列为有序的
    while i<j:
        sum=sorted_nums[i]+sorted_nums[j]

        if sum>target:
            j-=1
        elif sum<target:
            i+=1
        else:#返回未排序之前对应的下标索引;使用.index方法实现
            index1=nums.index(sorted_nums[i])
            index2=nums.index(sorted_nums[j])
            return [index1,index2]

题目2:移除元素-27

(1)思路:定义两个指针i,j:i指针用于存放与目标值不相等的元素;j指针用于遍历数组

class Solution:
    def removeElement(self, nums, val: int) -> int:
        low,fast=0,0
        while fast<len(nums):
            if nums[fast]!=val:
                nums[low]=nums[fast]#将元素移到数组首部
                low+=1#移动到数组下一个位置
            fast+=1#继续遍历数组
        return low

二:对撞双指针

题目1:反转字符串-344
(1)思路:定义两个指针left,right;然后交换元素完成题目要求;也可以使用遍历反转;容器切片等操作进行反转

def func(s):
    left=0
    right=len(s)-1
    while left<right:
        s[left],s[right]=s[right],s[left]#核心语句
        #如果直接是s[left]=s[right]的话,s[left]的值就丢失了
        #无法达到反转字符的效果
        left+=1
        right-=1
    retrun s

题目2 三数求和-15

(1)思路:定义两个指针;首先对数组进行排序;然后初始化左指针和右指针;左指针指向数组的第二个元素;右指针指向数组左右一个元素;判断的过程就是先遍历数组;取出第一个元素;然后通过双指针找其他两个数与第一个数加起来等于目标值的元素!如果有的话就返回这个三个数;同时也要判断元组不能重复!

class Solution:
    def threeSum(self, nums):
        nums.sort()  # 首先对数组进行排序
        result = []  # 用于存储满足条件的三元组
        for i in range(len(nums)):
            left = i + 1  # 初始化左指针,指向当前元素的下一个位置
            right = len(nums) - 1  # 初始化右指针,指向数组的末尾
            if nums[i] > 0:  # 如果当前元素大于0,则后续三数之和必然大于0,直接结束循环
                break
            if i >= 1 and nums[i] == nums[i - 1]:  # 跳过重复元素,避免重复的三元组
                continue
            while left < right:
                target = nums[i] + nums[left] + nums[right]  # 计算三数之和
                if target < 0:  # 如果和小于0,左指针右移以增大总和
                    left += 1
                elif target > 0:  # 如果和大于0,右指针左移以减小总和
                    right -= 1
                else:  # 找到满足条件的三元组
                    result.append([nums[i], nums[left], nums[right]])
                    # 跳过重复的左指针元素
                    while left < right and nums[left] == nums[left + 1]:
                        left += 1
                    # 跳过重复的右指针元素
                    while left < right and nums[right] == nums[right - 1]:
                        right -= 1
                    # 移动指针继续寻找其他可能的三元组
                    left += 1
                    right -= 1
        return result  # 返回最终的结果列表

题目3 救生艇-881

(1)思路:双指针问题;就是简单的过船问题:两个人的体重和小于目标值的时候;可以过河;如果两个人的体重和大于目标值;说明体重大的那个人需要一个人坐一个船;直接对撞双指针拿下!

class Solution:
    def numRescueBoats(self, people,limit) -> int:
        people.sort()
        left, right = 0, len(people) - 1
        count = 0

        while left <= right:
            if people[left] + people[right] <= limit:
                left += 1#就是两个人同时上传;移动指针判断下一组元素
                right -= 1
            else:
                right -= 1#体重大的人一个人上船
            count += 1
        return count

三:快慢双指针

题目1:环形链表-141

(1)思路:经典的龟兔赛跑算法;也成为快慢双指针;定义一个慢指针和一个快指针;如果链表是环形的话;那么快指针和慢指针会相遇;如果不相遇说明就不是环形链表:慢指针每次向前移动一位;快指针每次向前移动两位;如果链表有环的话纳闷slow和fast始终会相遇的

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

def hasCycle(head):
    if not head or not head.next:
        return False
    slow = head#慢指针指向头节点
    fast = head.next#快指针指向第二个节点
    while slow != fast:
        if not fast or not fast.next:
            return False
        slow = slow.next#向前移动一步
        fast = fast.next.next#向前移动两部

    return True

标签:right,nums,元素,fast,算法,指针,LeetCode,left
From: https://www.cnblogs.com/gsupl/p/18406829

相关文章

  • 72. 编辑距离(leetcode)
    https://leetcode.cn/problems/edit-distance/classSolution{publicintminDistance(Stringword1,Stringword2){//经典题编辑距离//f[i][j]表示word1前i个字符中选择进行操作,word2前j个字符进行选择进行操作相同的最少步数//以word1[......
  • 583. 两个字符串的删除操作(leetcode)
    https://leetcode.cn/problems/delete-operation-for-two-strings/solutions/两种做法,1.直接dp2.转换题意,思考成LCSclassSolution{publicintminDistance(Stringword1,Stringword2){//编辑距离的简化版//f[i][j]表示word1前i个字符中选择,wo......
  • 【自用21.】C++-this指针
    Human::Human(intage,intsalary){ cout<<"调用自定义的构造函数"<<endl; this->age=age;//this是一个特殊的指针,指向这个对象本身 this->salary=salary; name="无名"; addr=newchar[64]; strcpy_s(addr,64,"China");}......
  • LeetCode Hot100刷题记录-234.回文链表
    题目:给你一个单链表的头节点head,请你判断该链表是否为回文链表。如果是,返回true;否则,返回false。PS:回文序列是向前和向后读都相同的序列。解题思路:遍历链表,将每个元素存放入一个新的数组中。遍历完成后,再用两个指针前后遍历数组来判断两个数字是否相等。/***Def......
  • 线性dp:LeetCode122.买卖股票的最佳时机ll
    买卖股票本文所讲解的内容与LeetCode122.买卖股票的最佳时机ll,这道题题意相同,阅读完本文后可以自行挑战一下力扣链接题目叙述:给定一个长度为N的数组,数组中的第i个数字表示一个给定股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交......
  • leetcode day06 动态规划之解码方法I和II
    91.解码方法该题类似于爬楼梯方法一:动态规划对于给定的字符串s,设它的长度为n,其中的字符从左到右依次为s[1],s[2],⋯,s[n]。我们可以使用动态规划的方法计算出字符串s的解码方法数。具体地,设f i 表示字符串s的前i个字符s[1..i]的解码方法数。在进行状态转移......
  • LeetCode之数组/字符串
    88.合并两个有序数组classSolution{publicvoidmerge(int[]nums1,intm,int[]nums2,intn){//这个循环将nums2中的元素逐个复制到nums1中从索引m开始的位置for(inti=0;i<n;i++){nums1[i+m]=nums2[i];......
  • 易百纳ss928开发板移植自训练模型跑通yolov5算法
    ss928平台移植官方yolov5s算法参考文章:https://www.ebaina.com/articles/140000017418,这位大佬也开源了代码,gitee链接:https://gitee.com/apchy_ll/ss928_yolov5s本文在参考上述文章的基础上,将官方yolov5s模型跑通,验证推理图片正确,然后移植自训练的推理模型,在移植过程中遇到了一些......
  • LeetCode: 2552. 统计上升四元组 动态规划 时间复杂度O(n*n)
    2552.统计上升四元组today2552.统计上升四元组题目描述给你一个长度为n下标从0开始的整数数组nums,它包含1到n的所有数字,请你返回上升四元组的数目。如果一个四元组(i,j,k,l)满足以下条件,我们称它是上升的:0<=i<j<k<l<n且nums[i]<nums[k]<num......
  • 常见的排序算法
    算法分类1、排序比较类排序2、复杂度相关概念稳定:如果a本来在b前面,而a=b,排序之后a仍然在b的前面不稳定:如果a本来在b的前面,而a=b,排序之后a可能在b的后面时间复杂度:对排序数据的总的操作数,反映当n变化时,操作次数呈什么变化空间复杂度:指算法计算......