leetcode-双指针法【三刷done】

1、移除元素(用的不是双指针)

27 移除元素

2、反转字符串(用的不是双指针)

344 反转字符串

class Solution:
    def reverseString(self, s: List[str]) -> None:
        s[:] = s[::-1]
        return s

3、替换空格(用的不是双指针)

05 替换空格

4、翻转字符串里的单词(用的不是双指针)

151 翻转字符串里的单词

class Solution:
    def reverseWords(self, s: str) -> str:
        return ' '.join(s.split()[::-1])

5、反转链表(更新pre、cur指针需注意顺序)

206 反转链表

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head 

        while cur :
            tmp = cur.next    ## 保存一下 cur的下一个节点,因为接下来要改变cur->next
            cur.next  = pre   #反转
            #更新pre、cur指针
            pre = cur
            cur = tmp
        return pre

6、删除链表的倒数第N个节点(return dummy.next)

19 删除链表的倒数第N个节点
1 、初始时first 和second 均指向头节点。我们首先使用first 对链表进行遍历,遍历的次数为 n。此时,first 和second 之间间隔了 n-1 个节点,即first 比second 超前了 n 个节点。
在这之后,我们同时使用first 和second 对链表进行遍历。当first 遍历到链表的末尾(即first 为空指针)时,second 恰好指向倒数第 n个节点。
2、在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的next 指针指向链表的头节点。这样一来,我们就不需要对头节点进行特殊的判断了。
⚠️return dummy.next 而非second

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0, head)
        first = head
        second = dummy
        for i in range(n):
            first = first.next

        while first:
            first = first.next
            second = second.next
        
        second.next = second.next.next
        return dummy.next

7、链表相交

0207 链表相交

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        if not headA or not headB:
            return None

        a = headA
        b = headB
        while a != b:
            a = a.next if a else headB
            b = b.next if b else headA
        return a

8、环形链表

142 环形链表
分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            # 如果相遇
            if slow == fast:
                p = head
                q = slow
                while p!=q:
                    p = p.next
                    q = q.next
                #你也可以return q
                return p

        return None

9、三数之和(排序+双指针)

15 三数之和

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        ans = []
        
        for i in range(n):
            if nums[i] > 0:  #第一个数就大于0,不存在
                break 
            if i > 0 and nums[i] == nums[i-1]: #对第一个数去重
                continue 
            left = i+1
            right = n-1 
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total > 0: right -= 1
                elif total < 0 : left += 1
                else:
                    ans.append([nums[i],nums[left], nums[right]])
                    while left < right and nums[left] == nums[left+1]: left +=1 #对第二个数去重
                    while left < right and nums[right] == nums[right-1]: right -=1  #对第三个数去重
                    left += 1
                    right -= 1
        return ans

10、四数之和(排序+双指针)

18 四数之和

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        ans = []
        
        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]: continue #对第一个数去重
            for j in range(i+1,n):
                if j > i+1 and nums[j] == nums[j-1]: continue  #对第二个数去重
                left = j+1
                right = n-1 
                while left < right:
                    total = nums[i] + nums[j] +  nums[left] + nums[right]
                    if total > target: right -= 1
                    elif total < target : left += 1
                    else:
                        ans.append([nums[i],nums[j],nums[left], nums[right]])
                        while left < right and nums[left] == nums[left+1]: left +=1 #对第三个数去重
                        while left < right and nums[right] == nums[right-1]: right -=1  #对第四个数去重
                        left += 1
                        right -= 1
        return ans

11、盛最多水的容器(双指针)

11. 盛最多水的容器

class Solution:
    def maxArea(self, height: List[int]) -> int:
       
        l,r = 0,len(height)-1
        max_area = 0
        while l <=r:
            max_area = max(max_area, (r-l)*min(height[l],height[r]))
            #移动矮的
            if height[l] <= height[r]:
                l += 1
            else:
                r -= 1
        return max_area

12、16. 最接近的三数之和

16. 最接近的三数之和

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        n = len(nums)
        best = 10**7
        
        def update(cur):
            nonlocal best
            if abs(cur-target) < abs(best-target):
                best = cur 
        
        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]:  #第一个数去重
                continue 
            
            left = i+1
            right = n-1 
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total == target:
                    return total 
                update(total)

                if total > target:
                    r = right - 1  #右指针左移
                    #去重
                    while left < r and nums[r] == nums[right]:
                        r -= 1
                    right = r 
                else:
                    l = left + 1  #左指针右移
                    #去重
                    while l < right and nums[l] == nums[left]:
                        l += 1
                    left = l
        return best 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值