力扣141题、142题、83题、167题(快慢指针,左右指针)
141、环形链表
基本思想:
使用快慢指针,如果是环形的,快指针一定会追上慢指针
具体实现:
循环让快慢指针往后跑,
循环条件是快指针不等于慢指针,
快指针等于慢指针则跳出循环
如果在循环内,快指针指向了null,
跳出循环返回不是环形链表
代码:
class Solution: def hasCycle(self, head: ListNode) -> bool: if not head or not head.next: return False slow = head fast = head.next while slow != fast: if not fast or not fast.next: return False slow = slow.next fast = fast.next.next return True
class Solution: def detectCycle(self, head: ListNode) -> ListNode: fast, slow = head, head while True: if not (fast and fast.next): return fast, slow = fast.next.next, slow.next if fast == slow: break fast = head while fast != slow: fast, slow = fast.next, slow.next return fast
public class Solution { public boolean hasCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while (fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if (fast == slow) return true; } return false; } }
142、环形链表II
基本思想:
快慢指针
具体实现:
1、快慢指针相遇时,慢指针走了k步,快指针走了2k步
2、设环起点到相遇点距离为m
3、k-m是头结点到环起点的距离
从相遇点到环起点的距离也是k-m
4、让两个指针的速度统一,都一步一个节点,
一个指针从头结点走,走到环起点走了k-m步
一个指针从相遇点走,走到环起点走了k-m步
两个指针这样相遇则是环起点
代码:
class Solution: def detectCycle(self, head: ListNode) -> ListNode: fast, slow = head, head while True: if not (fast and fast.next): return fast, slow = fast.next.next, slow.next if fast == slow: break fast = head while fast != slow: fast, slow = fast.next, slow.next return fast
public class Solution { public ListNode detectCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while (fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if (fast == slow) { fast = head; while (fast != slow){ fast = fast.next; slow = slow.next; } return fast; } } return null; } }
167、两数之和II
基本思想:
左、右指针
具体实现:
类似于二分搜索
代码:
class Solution: def twoSum(self, numbers: List[int], target: int) -> List[int]: left = 0 right = len(numbers)-1 res = [] while left < right: twosum = numbers[left] + numbers[right] if twosum == target: res.append(left+1) res.append(right+1) return res elif twosum < target: left += 1 else: right -= 1 return -1
83、删除排序链表中的重复元素
具体实现:
慢指针走在后面,快指针走在前面探路,找到一个不重复的元素就让慢指针指向快指针,指针快指针遍历完整个链表
代码:
class Solution: def deleteDuplicates(self, head: ListNode) -> ListNode: if not head: return head slow = head fast = slow.next while fast: if slow.val != fast.val: slow.next = fast slow = slow.next fast = fast.next slow.next = None return head