leetcode刷题记第19题解法(python解析)

leetcode刷题记--> 19题解法(python解析)

  • 题目定义
  • 解题
    • 1. 转为列表,然后再转为链表
    • 2. 使用递归的思路
    • 3. 使用字典存储的方法
    • 4. 使用单指针
    • 5. 使用双指针
      • 实现

题目定义

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

来源:力扣(LeetCode)
链接: leetcode_19题.

解题

本次使用4种方法,在leetcode上还有更多的方法,只能说真牛逼,真聪明。

1. 转为列表,然后再转为链表

先将链表转为列表,然后将列表转换为链表

2. 使用递归的思路

需要自己debug来进行理解

3. 使用字典存储的方法

首先将链表分为不同的节点进行存储,然后一步步的将链表进行替换

4. 使用单指针

定义单指针
先计算出链表的长度
然后通过链表长度减去n 就是要铲除的那个节点的前一个节点
然后循环

5. 使用双指针

定义双指针
先让first指针先走 先走n步
然后再让first和second同时走 当first走到末尾的时候 second也就走到要删除的那个节点的前一个节点 其实就是两者的一个差值

===================================================

实现

// An highlighted block
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:


    def removeNthFromEnd(self, head, n):
        '''
         就是将链表转为列表  然后通过列表将需要删的值删掉   然后再把列表转为链表(此处需要注意浅拷贝和深拷贝)
        '''

        # 边界值
        if not head or n <= 0:
            return None

        # 转成列表
        l = []
        while head:
            l.append(head.val)
            head = head.next
        # 防越界
        if n > len(l):
            return None

        # 使用pop()移除倒数第n个数后,转为链表
        l.pop(-n)
        new_head = ListNode(0)
        p = new_head  # 注意此处为浅拷贝   p变了   new_head 也会变  #相当于是一个指针
        for j in l:
            p.next = ListNode(j)
            p = p.next
        # 打印出结果
        # while new_head:
        #     print(new_head.val)
        #     new_head = new_head.next

        return new_head.next
    def removeNthFromEnd_1(self, head, n):
        '''
        递归
        '''
        def removeNode(node, n) :
            if node.next == None:
                return 1

            m = removeNode(node.next, n)
            if m == n:
                if m == 1:
                    node.next = None
                else:
                    node.next = node.next.next
            return m + 1

        return head.next if removeNode(head,n)==n else head
    def removeNthFromEnd_2(self, head, n):
        '''
        使用字典
        '''
        dummy = ListNode(0)
        dummy.next = head
        hash_key = {}
        head2 = dummy
        i=0
        while head2.next!=None:
            hash_key[i]=head2
            head2 = head2.next
            i+=1

        hash_key[i]=head2
        hash_key[i - n  ].next = hash_key.get(i-n+2)

        return dummy.next

    def removeNthFromEnd_3(self, head, n):
        '''

        定义单指针
        先计算出链表的长度
        然后通过链表长度减去n 就是要铲除的那个节点的前一个节点
        然后循环
        '''
        dummy = ListNode(0)
        dummy.next=head
        length = 0
        first = head
        # 找见链表有多长
        while first:
            length+=1
            first = first.next

        length-=n

        first = dummy  # 重新给first赋值

        while length>0:
            length-=1  # 2  1
            first=first.next

        first.next = first.next.next
        return dummy.next

    def removeNthFromEnd_4(self, head, n):
        '''
        定义双指针
        先让first指针先走   先走n步
        然后再让first和second同时走   当first走到末尾的时候   second也就走到要删除的那个节点的前一个节点  其实就是两者的一个差值
        '''
        dummy = ListNode(0)
        dummy.next = head
        first = dummy
        second = dummy
        # 先让first 走n 步
        for i in range(0,n+1):
            first = first.next


        while first: #   second和first同时往前走    当first走到头时,second即是要删除节点的前一个节点位置
            first = first.next
            second = second.next

        second.next = second.next.next
        return dummy.next




    def print_node(self,node):


        while node:
            print(node.val)
            node = node.next


a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
d = ListNode(4)
e = ListNode(5)
f = ListNode(6)

a.next = b
b.next = c
c.next = d
d.next = e
e.next = f
s = Solution()

node = s.removeNthFromEnd_1(a,2)
s.print_node(node)

你可能感兴趣的:(leetcode)