首页 > 其他分享 >day4 | 19. 删除链表的倒数第N个结点,24. 两两交换链表中的节点,

day4 | 19. 删除链表的倒数第N个结点,24. 两两交换链表中的节点,

时间:2023-03-18 19:57:32浏览次数:57  
标签:24 head cur 19 结点 fast next 链表

19. 删除链表的倒数第N个结点

 

题目描述

 

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

 

思路

 

1. 先确定链表结点数,得到length

2. 再遍历到第length-n个结点上,改变其指针域上面的值为指向下下的结点,或者说使得指针域的值和下一个结点内指针域的值相等,实现删除第n个结点的功能

3. 暂且不考虑特殊情况,取cur=head,遍历length-n-1次到达目的地,此时cur指向第length-n个结点,执行上一步指针域重新赋值的操作

4. 考虑特殊情况,单列出来,当length-n=0,那么length-1小于小于0,会出现问题。

5. 单独解决这个问题,创建一个虚拟头指针,等于说是实现了cur向右移动-1步的操作,然后再执行指针域重新赋值的操作,返回dummy.next。

(貌似leetcode中的head就是第一个结点地址的意思,head.value就是第一个值,head.next就是下一个节点的地址值)

 

代码如下

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        def getlength(head):
            cur=head
            length=0
            while(cur!=None):
                cur=cur.next
                length+=1
            return length
        
        nn=getlength(head)
        dummy=ListNode(next=head)
        del_num_front=nn-n
        cur=head
        if del_num_front==0:
            # head=head.next # 这样写其实也行
            dummy.next=dummy.next.next
            return dummy.next
        else:
            for i in range(del_num_front-1):
                cur=cur.next
  
            cur.next=cur.next.next
           return head

 

看了答案改进后的代码,可以从一开始就用虚拟头结点。

 

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head 

        #step1: 获取链表长度
        cur, length = head, 0 
        while cur:
            length += 1
            cur = cur.next 
        
        #step2: 找到倒数第N个节点的前面一个节点
        cur = dummy
        for _ in range(length - n):
            cur = cur.next
        
        #step3: 删除节点,并重新连接
        cur.next = cur.next.next
        return dummy.next 

 

 

24. 两两交换链表中的结点

 

题目简述

 

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

 

思路

 

迭代交换

1. 创建哑结点dummyHead,令dummyHead.next=head。

2. 令temp表示当前到达的结点,初始时temp=dummyHead,每次交换temp后面的两个结点

3. 交换之前结点关系temp→node1→node2,交换之后temp→node2→node1

 

代码如下

 

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummyHead = ListNode(0)
        dummyHead.next = head
        temp = dummyHead
        while temp.next and temp.next.next:
            node1 = temp.next
            node2 = temp.next.next
            temp.next = node2
            node1.next = node2.next # 这一句和下一句不能交换,否则找不到node2.next了
            node2.next = node1 
            temp = node1
        return dummyHead.next

 

 

142. 环形链表

 

题目描述 略

 

思路:

 

快慢指针法

1. 定义fast和slow指针,fast每次走两步,slow每次走1步

2. 假设head离入口处有a步距离;从入口处到最右侧有b-1个结点,不计算入口处结点,那么从入口处出发,再次回到入口处,需要走k步;如此,链表总计有a+k的结点。

3. 假设slow在离循环入口b步处与fast相遇,那么应该有a+nk+b=2a+2b,a=nk-b,令k=b+c,则有a=c+(n-1)(b+c),从相遇点到入环点的距离加上n-1圈的环长,恰好等于从链表头部到入环点的距离

4. 因此,当发现slow与fast相遇时,我们在额外使用一个指针ptr。起始,它指向链表头部;随后,它和slow每次向后移动一个单位。最终,它们会在入环点相遇

 

代码如如下

class Solution(object):
    def detectCycle(self, head):
        fast, slow = head, head
        while True:
            if not (fast and fast.next): return
            fast, slow = fast.next.next, slow.next
            if fast == slow: break
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast。

 

 

面试题 02.07. 链表相交

 

题目描述

 

给你两个单链表的头结点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。

 

思路

如这题应该是比较明显的双指针题,要是能实现一种算法让两个指针分别从A和B点往C点走,两个指针分别走到C后,又各自从另外一个指针的起点,也就是A指针第二次走从B点开始走,B指针同理,这样,A指针走的路径长度 AO + OC + BO 必定等于B指针走的路径长度 BO + OC + AO,这也就意味着这两个指针第二轮走必定会在O点相遇,相遇后也即到达了退出循环的条件。

 

代码如下

 

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        ta, tb = headA, headB
        while ta != tb:
            ta = ta.next if ta else headB
            tb = tb.next if tb else headA
        return tb

 

 

 

总结


1. leetcode里面的头结点貌似就是第一个结点

2. 学会使用快慢指针法

3. 学会面试题中的互补思想

 

标签:24,head,cur,19,结点,fast,next,链表
From: https://www.cnblogs.com/cp1999/p/17231148.html

相关文章

  • 数据结构-->链表_02
    本期的链表继续进行,上期我们完成了链表的增加和删除。现在接下来,我们进行链表的查改与优化头文件“SList.h”#include<stdio.h>#include<assert.h>#include<stdlib.h>typ......
  • [ABC245E] Wrapping Chocolate题解
    听说没人写,那就来一发。这种偏序问题大概率是要排个序的。将盒子和巧克力视为一个东西,\(c\)视为\(a\),\(d\)视为\(b\),放在一起以\(a\)为第一关键字,\(b\)为第二关键......
  • Kubernetes 1.24 Ubuntu18.04安装
    集群清单角色系统配置IP系统Master最低双核2G内存30G硬盘192.168.56.130Ubuntu18.04Node最低双核2G内存30G硬盘192.168.56.129Ubuntu18.04一、......
  • 19. 删除链表的倒数第 N 个结点
    19.删除链表的倒数第N个结点给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=......
  • 24.两两交换链表中的结点
    24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入......
  • 142.环形链表plus
    142.环形链表II给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链......
  • 面试题 02.07链表相交
    面试题02.07.链表相交给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。图示两个链表在节点c1开......
  • 双链表
    双链表双链表有两个指针,一个指向前一个指向后,数组模拟链表实现思想双链表有两个指针,一个指向前一个指向后,故定义三个数组\(l[N],r[N],val[N]\)\(l[N]指向的是当前......
  • day19
    day19释放资源的方式close()try-catch-finallyfinally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止。作用:一般用于......
  • 力扣 142 环形链表
    判断一个链表有无环,并且如果有环指出入环的位置。1、判断有无环是通过一快一慢指针来判断的。快的指针走每次走两步、慢的指针每次走一步,这样如果没有环的话他俩不会相遇......