我是靠谱客的博主 忐忑煎饼,最近开发中收集的这篇文章主要介绍算法系列:双指针——快慢指针、左右指针、滑动窗口前言结语,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

本篇归纳双指针算法

  • 快慢指针:主要是成环问题
  • 左右指针:数组和字符串问题
  • 滑动窗口:主要是子串问题

1、快慢指针

快慢指针
顾名思义
思路简单清晰
直接看下2个经典问题

链表是否有环

leet上141题

给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos 是 -1,则在该链表中没有环。

快慢指针
如果有环,迟早会相遇

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        fast, slow = head, head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow: return True
        return False

链表中有环,返回环的起始位置

leet上142题

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 
如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。

当快慢指针相遇时,让其中任⼀个指针指向头节点
然后让它俩以相同速度前进,再次相遇时所在的节点位置就是环开始的位置

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast, slow = head, head
        while True:
            if not (fast and fast.next): return 
            fast, slow = fast.next.next, slow.next
            if fast == slow: break
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast

2、左右指针

通常在数组中

left = 0, right =len(nums) - 1

来看道题

最接近的三数之和

leet上第16题

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。
找出 nums 中的三个整数,使得它们的和与 target 最接近。
返回这三个数的和。假定每组输入只存在唯一答案。
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        res = float("inf")
        for i in range(len(nums)-1):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l, r = i + 1, len(nums) - 1
            while l < r:
                cur = nums[i] + nums[l] + nums[r]
                if cur == target: return target
                if abs(res - target) > abs(cur - target):
                    res = cur
                if cur > target:
                    r -= 1
                elif cur <= target:
                    l += 1
        return res

3、滑动窗口

思路简单
维护⼀个窗⼝,不断滑动,然后更新答案

下面看几道经典题

无重复字符的最长子串

leet上第3题

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:max_len = cur_len
            lookup.add(s[i])
        return max_len

最小覆盖子串

leet上76题

给你一个字符串 S、一个字符串 T 。
请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        if not s or len(s) < len(t): return ""
        from collections import Counter
        t = Counter(t)
        lookup = Counter()
        start, end = 0, 0
        min_len = float("inf")
        res = ""
        while end < len(s):
            lookup[s[end]] += 1
            end += 1
            while all(map(lambda x: lookup[x] >= t[x], t.keys())):
                if end - start < min_len:
                    res = s[start:end]
                    min_len = end - start
                lookup[s[start]] -= 1
                start += 1
        return res

至多包含 K 个不同字符的最长子串

leet上340题

class Solution:
    def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
        from collections import defaultdict
        lookup = defaultdict(int)
        start = 0
        end = 0
        max_len = 0
        counter = 0
        while end < len(s):
            if lookup[s[end]] == 0:
                counter += 1
            lookup[s[end]] += 1
            end += 1
            while counter > k:
                if lookup[s[start]] == 1:
                    counter -= 1
                lookup[s[start]] -= 1
                start += 1
            max_len = max(max_len, end - start)
        return max_len

结语

双指针算法思路简单清晰
就是边界条件需要思考下

最后

以上就是忐忑煎饼为你收集整理的算法系列:双指针——快慢指针、左右指针、滑动窗口前言结语的全部内容,希望文章能够帮你解决算法系列:双指针——快慢指针、左右指针、滑动窗口前言结语所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部