算法学习(三)

算法# 学习目标:双指针(一)

  • 学习内容:
  • 学习产出:
  • 对撞指针
    • 题解
    • 代码(python)
  • 快慢指针
    • 题解
    • 代码(python)

学习内容:

双指针:两个指针指向不同元素,从而协同完成任务,主要用于遍历元素。

学习产出:

对撞指针,快慢指针,滑动窗口

对撞指针

对撞指针是指在数组中,将指向最左侧的索引定义为左指针,最右侧的定义为右指针,然后从两头向中间进行数组遍历。

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]
解释:27 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

使用对撞指针,初始化一个指针指向最左,一个指针指向最右,相向遍历,如果两者之和小于给定值,则左指针向右移一位,否则右指针向左移一位

步骤:

  1. 初始化双指针
  2. 寻找目标值

代码(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张图片


示例1

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

初始化两个指针,快指针前进两步,慢指针前进一步,如果存在环路则快指针可以无限循环下去,并与慢指针在某一时刻相遇。否则,快指针可以走到尽头。当第一次相遇,将快指针重新回到表头,,并让其每次前进一步,则第二次相遇即为环路开始点

步骤:

  1. 初始化双指针
  2. 寻找第一次相遇
  3. 重新初始化
  4. 寻找第二次相遇

代码(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

你可能感兴趣的:(指针,链表,算法,leetcode)