Leetcode日练笔记31 #19 #206 # 203 Rmv Nth Node From End & Reverse Linked List & Rmv Linked List Elements

Given the head of a linked list, remove the nth node from the end of the list and return its head.

Example 1:

解题思路:

题目也是希望只traverse一遍,所以也是要用到双指针。一个是当下跑的,一个是当下-n的,就是要移除的点前一个点。

先让curr领跑n个点。然后再curr和prev一起跑,等到curr跑到最后一个点之后,让prev.next = prev.next.next.就删掉了prev后的那个点。

我自己也重写了一遍:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        curr = prev = head
        for _ in range(n):
            curr = curr.next
            
        if not curr:
            return head.next
        
        
        while curr.next:
            curr = curr.next
            prev = prev.next
        
        prev.next = prev.next.next
        
        return head

runtime:

#206 Reverse Linked List

Given the head of a singly linked list, reverse the list, and return the reversed list.

解题思路:

如果只traverse一遍的话,那么每经过一个店都要都点进行操作。摘下来作为一个新的linked list,然后新掉下来的点都放在新linked list的队头。新旧linked list都要有指针带着,掉下来的点也要有指针指向。所以一共要三个指针。

分别是prev,curr,nxt。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        prev = None
        curr = head
        
        while curr:
            nxt = curr.next
            curr.next = prev
            prev = curr
            curr = nxt
            
        return prev

runtime:

16ms的没差:

 

#203 Remove Linked List Elements

Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.

解题思路:

当node的val与目标值相同,则去掉当前的点,令prev.next  = curr.next。

关键是这个prev的值是否为None,换句话说就是curr这个点万一是第一个点怎么办,这个时候prev就为None,接不上下一个点。

所以安一个假头。sentinel = ListNode(0)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        sentinel = ListNode(0)
        sentinel.next = head
        
        prev, curr = sentinel, head
        while curr:
            if curr.val == val:
                prev.next = curr.next
            else:
                prev = curr
            curr = curr.next
        
        return sentinel.next

最后再返回sentinel.next就等于默认弃掉临时加的假头。

不加假头也行,forum里zayne-siew给的思路是:

分情况讨论,比如第一个就是要去掉的点的话,那么prev一开始是None,就不移动,只移动curr给curr.next。然后head改为head.next就好。如果prev已经有值,那么就是prev.next=curr.next。最后返回head。

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        prev, curr = None, head
        while curr:
            if curr.val == val:  # cases 1-3
                if prev:  # cases 1-2
                    prev.next = curr.next
                else:  # case 3
                    head = curr.next
                curr = curr.next  # for all cases
            else:  # case 4
                prev, curr = curr, curr.next
        return head
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值