面试刷题总结:双指针 & 滑动窗口 & 双端遍历 (LeetCode)

前言

双指针与滑动窗口是一类比较容易理解的题型
广泛应用于链表与数组类型题目中

题目列表

两个链表的第一个公共节点

https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof

输入两个链表,找出它们的第一个公共节点

题目ID:2322

  • 解题思路

根据两个链表长度和相同,指针速度相同总会相遇

两个跑速一样的人在不同长短的跑道里跑,怎么才能让他们遇见,不断交换他们的跑道

  • 实现代码
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        pA,pB = headA,headB
        while pA!=pB:
        	#if 后面换成pA.next将处理不了不相交的链表
            pA=pA.next if pA else headB 
            pB=pB.next if pB else headA
        return pA
  • 细节

两个链表不相交的情况下,指针各自跑完总路程同时指向空null


考试的最大困扰度

https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam

一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 ‘T’ 表示)或者 false (用 ‘F’ 表示)。老师想增加学生对自己做出答案的不确定性,方法是 最大化 有 连续相同 结果的题数。(也就是连续出现 true 或者连续出现 false)。

给你一个字符串 answerKey ,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k ,表示你能进行以下操作的最多次数:

每次操作中,将问题的正确答案改为 ‘T’ 或者 ‘F’ (也就是将 answerKey[i] 改为 ‘T’ 或者 ‘F’ )。
请你返回在不超过 k 次操作的情况下,最大 连续 ‘T’ 或者 ‘F’ 的数目。

  • 解题思路:

双指针每次固定right,寻找符合条件的left并求最优解

  • 实现代码:
class Solution:
    def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:
        def maxConsecutiveChar(ch: str) -> int:
            ans, left, sum = 0, 0, 0
            for right in range(len(answerKey)):
                sum += answerKey[right] != ch
                while sum > k:
                    sum -= answerKey[left] != ch
                    left += 1
                ans = max(ans, right - left + 1)
            return ans
        return max(maxConsecutiveChar('T'), maxConsecutiveChar('F'))
  • 细节:
    两次计算也可以使用一次遍历
    同时使用leftT与leftF保存两种情况即可

字符的最短距离

https://leetcode-cn.com/problems/shortest-distance-to-a-character/

给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符。

返回一个整数数组 answer ,其中 answer.length == s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。

两个下标 i 和 j 之间的 距离 为 abs(i - j) ,其中 abs 是绝对值函数。

  • 解题思路:

从数组两头遍历两次
记录遇到的字符c的下标,c后面的字符answer赋值
初始化下标无穷大

  • 实现代码:
class Solution:
    def shortestToChar(self, s: str, c: str) -> List[int]:
        ans = [0] * (n:=len(s))
        idx = -inf
        for i, ch in enumerate(s):
            if ch == c:idx = i
            ans[i] = i - idx

        idx = inf
        for i in range(n - 1, -1, -1):
            if s[i] == c: idx = i
            ans[i] = min(ans[i],idx - i)
        return ans
  • 细节:
    海象运算符
    第一遍遍历直接赋值
    第二遍再判断大小min
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赛文X

觉得不错就打赏下呗mua~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值