前言
双指针与滑动窗口是一类比较容易理解的题型
广泛应用于链表与数组类型题目中
题目列表
两个链表的第一个公共节点
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