深度之眼讲解笔记——双指针

双指针 Two Pointer

双指针分为两种:对撞指针 & 快慢指针
常用数组中

对撞指针

LeetCode 167题目
经典题目: Two sum

方法一:暴力解法

时间复杂度:O(n^2)
缺点:没有应用数组本身特点性质

方法二:数组有序,二分搜索法

时间复杂度:O(nlogn)
二分搜索时间复杂度是O(logn)
i 从0-n遍历 O(n)
j 从i-n遍历用 二分搜索法 O(logn)

方法三:双指针法

在这里插入图片描述
数组nums有序的
左指针 i 右指针 j
判断nums[i] + nums[j] == target
如果小于,则 i + 1 ,i右移再判断
如果大于,则 j + 1, j左移再判断
直到 i 跟 j 相撞

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        # 时间复杂度O(n)
        # 空间复杂的O(1)
        i , j = 0, len(numbers)-1
        while i < j :
            if numbers[i] + numbers[j] == target:
                break
            elif numbers[i] + numbers[j] < target:
                i += 1;
            elif numbers[i] + numbers[j] > target:
                j -= 1;
        return [i+1, j+1]

对撞指针的应用

在这里插入图片描述

快慢指针

LeetCode 142题目
在这里插入图片描述
在这里插入图片描述
Set集合,增加条件空间复杂度为1,怎该方法不能使用

定义

在这里插入图片描述
在这里插入图片描述
步骤:

  1. 定义fast指针和slow指针,fast一次二步,slow一次一步
  2. 第一步fast->2, slow->3, fast->1,slow->2, fast->8, slow->7,fast->4,slow->1, fast->6,slow->6相遇!!!
  3. 定义一个指针p从最开始按照一次一步移动,和slow的频率一样,p和slow相遇的节点就是环的入口点。

证明:

  1. a = 从开始位置到入环口步数
  2. b = 一环的步数
  3. fast = 2 * slow
  4. fast = slow + nb
  5. slow = nb
# Definition for singly-linked list.
# 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 fast != None:
            fast = fast.next
            if fast == None:
                break
            fast = fast.next
            # fast 两步
            slow = slow.next
            # slow 一步
            if slow == fast:
                break
        if fast == None:
            return None
        p1, p2 = slow, head
        while p1 != p2:
            p1 = p1.next
            p2 = p2.next
        return p1
发布了6 篇原创文章 · 获赞 0 · 访问量 61

猜你喜欢

转载自blog.csdn.net/qq_35493320/article/details/104265091