代码随想录训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表

77 阅读2分钟

203.移除链表元素

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

删除一个节点最好还是用一个dummy_head,这样方便不同节点删除操作的一致性。

tmp_pt指向dummy_head, 判断tmp_pt.next是否是val, (1)如果是:tmp_pt.next = tmp_pt.next.next (2)如果不是:tmp_pt = tmp_pt.next 直到tmp_pt.next==None,因为我们每次判断的都是tmp_pt.next

# 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]:
        dummy_head = ListNode(val=-1, next=head)
        tmp_pt = dummy_head
        while tmp_pt.next != None:
            if tmp_pt.next.val == val:
                next_node = tmp_pt.next
                tmp_pt.next = tmp_pt.next.next
                del next_node
            else:
                tmp_pt = tmp_pt.next
        return dummy_head.

3. 实现过程中遇到的困难

陷入了死循环,犯了一个低级错误: tmp_pt = tmp_pt.next写成了tmp_pt.next = tmp_pt

4. 看完代码随想录之后的想法

和我想得差不多。

5. 学习时长

20分钟

707.设计链表

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

addAtIndex()方法应该可以用于实现addAtHead()addAtTail()

我们可以存链表的长度,这样可以及时判断get()是否合法。


class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class MyLinkedList:

    def __init__(self):
        self.len = 0
        self.dummy_head = ListNode()

    def get(self, index: int) -> int:
        if index >= self.len:
            return -1
        else:
            tmp_pt = self.dummy_head
            list_idx = 0
            while tmp_pt.next:
                if list_idx == index:
                    return tmp_pt.next.val
                else:
                    tmp_pt = tmp_pt.next
                    list_idx += 1
        return -1

    def addAtHead(self, val: int) -> None:
        self.addAtIndex(index=0, val=val)

    def addAtTail(self, val: int) -> None:
        self.addAtIndex(index=self.len, val=val)

    def addAtIndex(self, index: int, val: int) -> None:
        if self.len < index:
            return
        tmp_pt = self.dummy_head
        list_idx = 0
        while tmp_pt.next:
            if list_idx == index:
                tmp_next = tmp_pt.next
                tmp_pt.next = ListNode(val=val, next=tmp_next)
                break
            else:
                tmp_pt = tmp_pt.next
                list_idx += 1
        if index == self.len:
            tmp_pt.next = ListNode(val=val, next=None)
        self.len += 1

    def deleteAtIndex(self, index: int) -> None:
        if 0 <= index < self.len:
            list_idx = 0
            tmp_pt = self.dummy_head
            while tmp_pt.next:
                if list_idx == index:
                    tmp_pt.next = tmp_pt.next.next
                    break
                else:
                    tmp_pt = tmp_pt.next
                    list_idx += 1
            self.len -= 1



# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

3. 实现过程中遇到的困难

  1. 我在实现过程中加入创建的新节点,并没有将指针后移,且没有对list_idx也未能更新,导致反复创建节点内存溢出。
  2. 另外,self.len也没有及时更新,导致判断失效。

4. 看完代码随想录之后的想法

文档中使用for循环,只要到了for list_idx in range(index):就结束循环,得到的就是当前需要删除或添加node的前一个节点,操作就可以了。比while循环要简单很多。

5. 学习时长

206.反转链表

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

给定一个列表,那我们就可以使用三个指针:pre_pt, cur_pt, next_pt.

我们先用next_pt指向cur_pt.next, 防止本来cur_pt.next丢失。

再用cur_pt.next指向pre.

接下来,就要移动指针了,pre_pt指向cur_pt, cur_pt指向next_pt, next_pt指向next_pt.next.

但是我们需要两个节点才能做这个操作。

所以需要判断,如果是单个节点直接返回就好。

如果是两个及以上节点,返回cur_pt


# 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]:
        if head == None:
            return head
        pre_pt = None
        cur_pt = head
        next_pt = cur_pt.next
        if cur_pt.next == None:
            return cur_pt
        else:
            while next_pt:
                cur_pt.next = pre_pt
                pre_pt = cur_pt
                cur_pt = next_pt
                next_pt = cur_pt.next
            cur_pt.next = pre_pt
            return cur_pt
        

3. 实现过程中遇到的困难

最后需要再处理一下cur_pt, 因为最后的cur_pt.next==None, 所以不能执行一整个循环体。

4. 看完代码随想录之后的想法

大致上思想上和我想的一样,只是它的逻辑更简单,能够统一用循环体执行。

重写一遍:


# 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]:
        pre_pt = None
        cur_pt = head
        while cur_pt:
            next_pt = cur_pt.next
            cur_pt.next = pre_pt
            pre_pt = cur_pt
            cur_pt = next_pt
        return pre_pt

5. 学习时长

周五晚上出去嗨了,最后一题没计时。