算法# 学习目标:双指针(一)
学习内容:
双指针:两个指针指向不同元素,从而协同完成任务,主要用于遍历元素。
学习产出:
对撞指针,快慢指针,滑动窗口
对撞指针
对撞指针是指在数组中,将指向最左侧的索引定义为左指针,最右侧的定义为右指针,然后从两头向中间进行数组遍历。
LeetCode 167 两数之和 II - 输入有序数组
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
使用对撞指针,初始化一个指针指向最左,一个指针指向最右,相向遍历,如果两者之和小于给定值,则左指针向右移一位,否则右指针向左移一位
步骤:
- 初始化双指针
- 寻找目标值
代码(python)
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
k,i =len(numbers)-1,0
while i < k:
if numbers[i] +numbers[k] > target:
k-=1
elif numbers[i] +numbers[k] < target:
i+=1
else:
break
return [i+1,k+1]
快慢指针
快慢指针:两个指针从同一侧开始遍历数组,将这两个指针分别定义为快指针和慢指针,两个指针以不同的策略移动,直到两个指针的值相等(或其他特殊条件)为止,如快指针每次增长两个,慢指针每次增长一个。
LeetCode 142 环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
你是否可以使用 O(1) 空间解决此题?
示例1
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
初始化两个指针,快指针前进两步,慢指针前进一步,如果存在环路则快指针可以无限循环下去,并与慢指针在某一时刻相遇。否则,快指针可以走到尽头。当第一次相遇,将快指针重新回到表头,,并让其每次前进一步,则第二次相遇即为环路开始点
步骤:
- 初始化双指针
- 寻找第一次相遇
- 重新初始化
- 寻找第二次相遇
代码(python)
# 定义链表
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
#快慢指针
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
fast,slow = head,head #初始化快慢指针
while True:
if not (fast and fast.next): #判断快指针是否能无线循环
return
if fast == slow: #判断相遇
break
fast,slow = fast.next.next,slow.next #定义前进规则
fast = head #重新初始化
while fast != slow: #第二次相遇判断,查找起始点
fast,slow = fast.next,slow.next #定义规则
return fast
注:
python中链表定义与调用
1.定义链表
2.定义链表操作函数
3.调用
#定义链表(单链表)
class ListNode:
def __init__(self): #root节点默认None
self.val = None
self.next = None
#定义链表操作函数
class ListNode_handle:
def __init__(self):
self.cur_node = None
def add(self, data): #头插法插入新元素
node = ListNone()
node.val = data
node.next = self.cur_node
self.cur_node = node
return node
def print_ListNode(self,node):
while node:
print(node)
node = node.next
#链表初始化调用
ListNode_operate = ListNode_handle()
L1 = ListNode()
L1_list = [1,2,3]
for i in L1_list:
l1 = ListNode_operate.add(i)
ListNode_operate.print_ListNode(l1)
#输出结果
#3->2->1