代码随想录算法训练营第三天|链表| 203.移除链表元素、 707.设计链表、206.反转链表
203.移除链表元素
题目链接: 移除链表元素
思想:
- 定义一个头结点
- 找到待删除节点的前驱节点
代码:
python
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
pre_head = ListNode()
pre_head.next = head
temp_pre_head = pre_head
while temp_pre_head.next != None:
if temp_pre_head.next.val == val:
# 删除
del_node = temp_pre_head.next
temp_pre_head.next = del_node.next
del_node.next = None
else:
temp_pre_head = temp_pre_head.next
return pre_head.next
707.设计链表
题目链接: 设计链表
总结:
在带有头结点的前提下:
设计链表的基本方法我觉得有一下几个难点:
-
我想通过循环让指针指向index = n的结点,这个while循环的限制条件我应该如何定义?
当前指向的是链表的前驱节点,从前驱节点到index = n要经过0, 1, 2, 3, … , n 要经过n+1步移动 , 所以如果用while循环的话,限制条件应该是只要是index >= 0那么指针就像后移动,index=0为最后一次移动。 -
从链表中插入结点,要找到其前驱节点,删除节点也是用样的道理。
-
题中给的index如果大于链表的长度,应该怎么知道?
如果index–过程中没有小于0但是.next = null 了(有头节点情况下),那就是index 值大于链表长度。
代码:
python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList(object):
def __init__(self):
self.pre_head = ListNode()
self.size = 0
def get(self, index):
"""
:type index: int
:rtype: int
"""
# 判断index是否合法
if index < 0:
return -1
# index 如果大于0, 那就只存在两种情况,1. 可以找index值 2. index out of range
temp_pre_head = self.pre_head # 不能使用原始的头指针
while index >= 0 and temp_pre_head.next != None: # 有头结点的情况下,从前驱节点到index节点(下标从0开始)需要index + 1步,也就是包含0这个值,index存在out of range情况,所以要判断后面时候还有元素
index -= 1
temp_pre_head = temp_pre_head.next
if index < 0: # 如果index = -1说明index在链表长度范围内,返回对应的值即可
return temp_pre_head.val #
else:
return -1
def addAtHead(self, val):
"""
:type val: int
:rtype: None
"""
# 有头节点在,在开始位置插入一个新的结点可以说很简单
new_node = ListNode()
new_node.val = val
new_node.next = self.pre_head.next
self.pre_head.next = new_node
return None
def addAtTail(self, val):
"""
:type val: int
:rtype: None
"""
# 在尾部插入一个节点,只需找到当前尾结点即可
new_node = ListNode()
new_node.val = val
temp_pre_head = self.pre_head
while temp_pre_head.next != None:
temp_pre_head = temp_pre_head.next
temp_pre_head.next = new_node
return None
def addAtIndex(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
# 在指定index对应的结点之前插入一个新的结点,需要让指针移动到index对应的结点的前一个节点位置
new_node = ListNode()
new_node.val = val
if index < 0:
return None
temp_p = self.pre_head
while index > 0 and temp_p.next != None:
index -= 1
temp_p = temp_p.next
if index != 0 or temp_p == None:
return None
else:
new_node.next = temp_p.next
temp_p.next = new_node
return None
def deleteAtIndex(self, index):
"""
:type index: int
:rtype: None
"""
if index < 0:
return None
temp_p = self.pre_head
while index > 0 and temp_p.next != None:
index -= 1
temp_p = temp_p.next
if temp_p.next != None:
temp_p.next = temp_p.next.next
return None
# 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)
206.反转链表
题目链接: 反转链表
思想:
其实就是将原始的链表按照头插法重新来一遍
代码:
python
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 反转链表,其实就是将原始的链表按照头插法重新来一遍
if head == None:
return None
pre_head = ListNode()
p = head
while head.next != None:
p = head
head = head.next
p.next = pre_head.next
pre_head.next = p
head.next = pre_head.next
pre_head.next = head
return pre_head.next
总结
1. 做题很慢,希望接下来可以缕清思路,明确每一个细小的步骤,不要感觉!加油,一定要冷静,大脑转起来
2. java来建立链表其实就是通过类来定义一个链表结构,同c/c++不太一样,有专门的结构体函数,这个是一个区别
3. java如何要建立一个带头结点的链表,需要用到内部类的方式
4. 寻找链表中第index个元素,在用循环时不知道边界是啥,总容易懵,这个地方还需要加强,应该动笔画一下:无头结点,若index以0为开始,想找index索引所在元素的前一个元素位置应该怎么循环?for(i = 0; i < index-1; i++), …总之,我觉得应该找到适用于自己的方式,然后以后遇到同样的问题就采用这种方式了,慢慢来吧