双指针问题

常见题型有哪些?

这里我将其分为三种类类型,分别是:

  • 快慢指针(两个指针步长不同,一个步长大,一个步长小。典型的是一个步长为 1,另外一个步长为 2)

  • 左右端点指针(两个指针分别指向头尾,并往中间移动,步长关系不确定)

  • 固定间距指针(两个指针间距相同,步长相同)

  1. 快慢指针
    判断链表是否有环

    1)例题:力扣 287 题,一个是 142 题。

    2)读写指针。典型的是删除重复元素

    例题:80.删除排序数组中的重复项 II

    3)一次遍历(One Pass)求链表的中点

    具体算法是使用两个指针。快指针每次最两步,慢指针每次走一步,这样当快指针走到链表尾部的时候, 慢指针刚好到达链表中间位置。

  2. 左右端点指针
    1)二分查找,例题:leetcode1371

    2)有序数组。区别于上面的二分查找,这种算法指针移动是连续的,而不是跳跃性的,典型的是 LeetCode 的两数和,以及N数和系列问题。

  3. 固定间距指针
    1) 一次遍历(One Pass)求链表的倒数第 k 个元素

    2)固定窗口大小的滑动窗口

题目推荐(LeetCode):

  • 左右端点指针
    16.3Sum Closest (Medium)
	class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums=sorted(nums)
        closest=float('inf')
        n=len(nums)
        for i in range(n-2):#固定一个值
            l=i+1
            r=n-1
            while r>l:
                sum_=sum([nums[i],nums[l],nums[r]])
                diff=sum_-target
                if abs(diff)<abs(closest-target):#每次记录最小值
                    closest=sum_
                if diff<0:#每次都会移动,遍历所有可能结果
                    l+=1
                else:
                    r-=1
        return closest

713.Subarray Product Less Than K (Medium)

	class Solution(object):
    def numSubarrayProductLessThanK(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        n=len(nums)
        res=0
        prod=1
        l=0
        for r in range(n):
            prod*=nums[r]#一直往右乘
            while prod>=k and l<=r:#超了就左边的指标向右
                prod//=nums[l]
                l+=1
            res+=r-l+1#包括最右边的数往左数有多少个
                
        return res

Dutch National Flag Problem

  • 二分类型

    33.Search in Rotated Sorted Array (Medium)

    class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        n=len(nums)
        l,r=0,n-1
        while l<=r:
            m=(l+r)//2
            if nums[m]==target:
                return m
            if nums[m]<target:
                if nums[m]>=nums[l]:
                    l=m+1
                elif nums[m]<nums[l]:
                    if nums[l]<=target:
                        r=m-1
                    else:
                        l=m+1
            else:
                if nums[m]<nums[l]:
                    r=m-1
                else:
                    if nums[l]<=target:
                        r=m-1
                    else:
                        l=m+1
        return -1
                    
    

    875.Koko Eating Bananas(Medium)

    class Solution(object):
    def minEatingSpeed(self, piles, h):
        """
        :type piles: List[int]
        :type h: int
        :rtype: int
        """
        if len(piles)==h:return max(piles)
        l=1
        r=max(piles)
        while l<r:
            m=(l+r)//2
            res=sum([p//m+1 if p%m!=0 else p//m for p in piles])
            if res > h: 
                l = m + 1
            else:
                r = m
        return r
    

    881.Boats to Save People(Medium)

    class Solution(object):
    def numRescueBoats(self, people, limit):
        """
        :type people: List[int]
        :type limit: int
        :rtype: int
        """
        n=len(people)
        if n==1:return 1
        people=sorted(people)
        l=0
        r=n-1
        boat=0
        while l<=r:
            if people[r]+people[l]<=limit:
                l+=1
            boat+=1
            r-=1
        return boat
    
  • 快慢指针
    26.Remove Duplicates from Sorted Array(Easy)

    class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow_pointer=0
        for i,num in enumerate(nums):
            if i>0 and num>nums[slow_pointer]:
                slow_pointer+=1
                nums[slow_pointer]=num
        return slow_pointer+1
    

    141.Linked List Cycle (Easy)

    class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        fast=head
        slow=head
        while fast and fast.next:
            fast=fast.next.next
            slow=slow.next
            if fast==slow:
                break
        if not fast or not fast.next:
            return False
        return True
    

    142.Linked List Cycle II(Medium)

    class Solution:
    def detectCycle(self, head):
        faster=head
        slower=head
        while faster!=None and faster.next!=None:
            faster=faster.next.next
            slower=slower.next
            if faster==slower:
                slow=head
                while slow!=slower:
                    slower=slower.next
                    slow=slow.next
                return slow
        return None
    

    287.Find the Duplicate Number(Medium)

    class Solution(object):
    def findDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        #数字范围:1-n,指标范围:0-n,存在两个指标对应一个数字
        #链表:把指标看成节点val,把数字看成节点指针next
        #nums = [1,3,4,2,2]
        #指标->数字
        #0->1
        #1->3
        #3->2
        #2->4
        #4->2
        #2->4
        #4->2
        #...
        #每个节点都要有next,形成一个环
        fast=0
        slow=0
        while True:
            fast=nums[nums[fast]]
            slow=nums[slow]
            if fast==slow:
                break
        finder=0
        while True:
            finder=nums[finder]
            slow=nums[slow]
            if finder==slow:
                return finder
    

    202.Happy Number (Easy)

    class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        slow=n
        fast=n
        while slow!=1:#不是happy number时一定存在循环
        #https://leetcode.com/problems/happy-number/discuss/56919/Explanation-of-why-those-posted-algorithms-are-mathematically-valid
            fast=self.NextHappy(fast)
            fast=self.NextHappy(fast)
            slow=self.NextHappy(slow)
            if fast==slow:
                return fast==1
        return True
    def NextHappy(self,n):
        res=0
        while n>0:
            m=n%10
            res+=m**2
            n/=10
        return res
    
  • 固定间距指针
    1456.Maximum Number of Vowels in a Substring of Given Length(Medium)

class Solution(object):
    def maxVowels(self, s, k):
        """
        :type s: str
        :type k: int
        :rtype: int
        """
        n=len(s)
        max_res=0
        res=0
        for i in range(n):
            if i>=k:
                if s[i-k] in ['a', 'e', 'i', 'o', 'u']:
                    res-=1
            if s[i] in ['a', 'e', 'i', 'o', 'u']:
                res+=1
            if max_res<res:
                max_res=res
        return max_res
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值