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

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

203.移除链表元素

题目链接: 移除链表元素

思想:

  1. 定义一个头结点
  2. 找到待删除节点的前驱节点

代码:

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.设计链表

题目链接: 设计链表

总结:
在带有头结点的前提下:
设计链表的基本方法我觉得有一下几个难点:

  1. 我想通过循环让指针指向index = n的结点,这个while循环的限制条件我应该如何定义?
    当前指向的是链表的前驱节点,从前驱节点到index = n要经过0, 1, 2, 3, … , n 要经过n+1步移动 , 所以如果用while循环的话,限制条件应该是只要是index >= 0那么指针就像后移动,index=0为最后一次移动。

  2. 从链表中插入结点,要找到其前驱节点,删除节点也是用样的道理。

  3. 题中给的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++), …总之,我觉得应该找到适用于自己的方式,然后以后遇到同样的问题就采用这种方式了,慢慢来吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值