双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多个数组的多个指针。
若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的区域即为当前的窗口),经常用于区间搜索。
若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是排好序的。
167. 两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组numbers
,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数target
的两个数。如果设这两个数分别是numbers[index1]
和numbers[index2]
,则1 <= index1 < index2 <= numbers.length
。
以长度为 2 的整数数组[index1, index2]
的形式返回这两个整数的下标index1
和index2
。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例1:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1, 2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例2:
输入: numbers = [2, 3, 4], target = 6
输出: [1, 3]
解释: 2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例3:
输入: numbers = [-1, 0], target = -1
输出: [1, 2]
解释: -1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
88. 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和nums2
,另有两个整数m
和n
,分别表示nums1
和nums2
中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意: 最终,合并后数组不应由函数返回,而是存储在数组nums1
中。为了应对这种情况,nums1
的初始长度为m + n
,其中前m
个元素表示应合并的元素,后n
个元素为0
,应忽略。nums2
的长度为n
。
示例1:
输入: nums1 = [1, 2, 3, 0, 0, 0], m = 3, nums2 = [2, 5, 6], n = 3
输出: [1, 2, 2, 3, 5, 6]
解释: 需要合并 [1, 2, 3] 和 [2, 5, 6] 。 合并结果是 [1, 2, 2, 3, 5, 6] ,
其中斜体加粗标注的为 nums1 中的元素。
示例2:
输入: nums1 = [1], m = 1, nums2 = [], n = 0
输出: [1]
解释: 需要合并 [1] 和 [] 。
合并结果是 [1] 。
示例3:
输入: nums1 = [0], m = 0, nums2 = [1], n = 1
输出: [1]
解释: 需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
142. 环形链表 II
给定一个链表的头节点head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。
如果链表中有某个节点,可以通过连续跟踪next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置 (索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例1:
输入: head = [3, 2, 0, -4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。
示例2:
输入: head = [1, 2], pos = 0
输出: 返回索引为 0 的链表节点
解释: 链表中有一个环,其尾部连接到第一个节点。
示例3:
输入: head = [1], pos = -1
输出: 返回 null
解释: 链表中没有环。
76. 最小覆盖子串
给你一个字符串s
、一个字符串t
。返回s
中涵盖t
所有字符的最小子串。如果s
中不存在涵盖t
所有字符的子串,则返回空字符串""
。
注意:
- 对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。- 如果
s
中存在这样的子串,我们保证它是唯一的答案。
示例1:
输入: s = “ADOBECODEBANC”, t = “ABC”
输出: “BANC”
示例2:
输入: s = “a”, t = “a”
输出: “a”
示例3:
输入: s = “a”, t = “aa”
输出: “”
解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
633. 平方数之和
给定一个非负整数c
,你要判断是否存在两个整数a
和b
,使得a2 + b2 = c
。
示例1:
输入: c = 5
输出: true
解释: 1 * 1 + 2 * 2 = 5
示例2:
输入: c = 3
输出: false
680. 验证回文字符串 Ⅱ
给定一个非空字符串s
,最多删除一个字符。判断是否能成为回文字符串。
示例1:
输入: s = “aba”
输出: true
示例2:
输入: s = “abca”
输出: true
解释: 你可以删除c字符。
示例3:
输入: s = “abc”
输出: false
524. 通过删除字母匹配到字典里最长单词
给你一个字符串s
和一个字符串数组dictionary
,找出并返回dictionary
中最长的字符串,该字符串可以通过删除s
中的某些字符得到。
如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。
示例1:
输入: s = “abpcplea”, dictionary = [“ale”, “apple”, “monkey”, “plea”]
输出: “apple”
示例2:
输入: s = “abpcplea”, dictionary = [“a”, “b”, “c”]
输出: “a”
340. 至多包含 K 个不同字符的最长子串
给定一个字符串s
,找出 至多 包含 k 个不同字符的最长子串T
。
示例1:
输入: s = “eceba”, k = 2
输出: 3
解释: 则 T 为 “ece”,所以长度为 3。
示例2:
输入: s = “aa”, k = 1
输出: 2
解释: 则 T 为 “aa”,所以长度为 2。