203.移除链表元素
1. 文章链接
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. 文章链接
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. 实现过程中遇到的困难
- 我在实现过程中加入创建的新节点,并没有将指针后移,且没有对
list_idx也未能更新,导致反复创建节点内存溢出。 - 另外,
self.len也没有及时更新,导致判断失效。
4. 看完代码随想录之后的想法
文档中使用for循环,只要到了for list_idx in range(index):就结束循环,得到的就是当前需要删除或添加node的前一个节点,操作就可以了。比while循环要简单很多。
5. 学习时长
206.反转链表
1. 文章链接
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. 学习时长
周五晚上出去嗨了,最后一题没计时。