链表系列入门指南(二):吃透这几题,链表解题不再难

前言

多的不说,先说重点,链表的核心解题点,都和链表的基本操作有关:添加、删除、翻转、头结点

解题思路

核心的思路就两个:

  1. 单链表需要往前倒数数的,考虑快慢指针
  2. 反转、删除、等基础操作,都依赖虚拟头节点,即当前位置k-1的节点,需要提前保存

删除倒数第n个链表节点 middle leetcode 19

时间3分钟

Golang 复制代码
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func removeNthFromEnd(head *ListNode, n int) *ListNode {
    h := &ListNode{Next: head}
    cnt := 0
    slowNode := h
    
    //倒数一般都是快慢指针
    //倒数第x个 那就距离第x个遍历到最后1个就行
    for node := h;node != nil;node=node.Next{
        if node.Next == nil{
            snodeNxt := slowNode.Next
            slowNode.Next = snodeNxt.Next
        }
        if cnt >= n{
            slowNode = slowNode.Next
        }
        cnt++
    }
    return h.Next
}

删除链表的重复值节点 middle leetcode 82

删除链表的第n个节点,比较简单,一个hash统计,一个链表删除 删除注意记录上一个节点就可以搞定

Golang 复制代码
func deleteDuplicates(head *ListNode) *ListNode {
    m := make(map[int]int)
    h := &ListNode{Next: head}
    for node:=head;node!=nil;node=node.Next{
        m[node.Val]++
    }

    lastNode := h
    for node:=head;node!=nil;node=node.Next{
        if m[node.Val]>=2{
            lastNode.Next = node.Next
        }else{
            lastNode = node
        }
    }
    return h.Next
}

旋转链表 middle leetcode 61

首先转换题意 等价于后k个节点插入到前面

后k个节点插入到链表首部 这个操作依赖4个节点 1. 倒数k+1个节点 断链后 前半部分的尾巴节点, 2. 断链后 后半部分首、尾节点 3. 虚拟头节点

如果K>=len链表长度,可以理解到,本质超过长度的部分可以算一个周期,直接求余,剩下来的长度仍然是后k%len 个要移动插入的节点 比如 k = 4 0,1,2 2往右边移动4次,本质相当于往右边移动1次 = 4 % 3

Golang 复制代码
func rotateRight(head *ListNode, k int) *ListNode {
    // 特殊判断只有1个或者为空的情况
    if head == nil || head.Next == nil{
        return head
    }
    h := &ListNode{Next: head}
    cnt := 0

    var oldTailNode *ListNode
    var lastKNode *ListNode
    lastKNode = h
    for node:=head;node!=nil;node=node.Next{
        cnt++
        oldTailNode = node
    }   
    k %= cnt
    // 如果不需要移动也直接返回
    if k == 0{
        return head
    }
    cnt = 0
    for node:=head;node!=nil;node=node.Next{
        cnt++
        if cnt >= k+1{
            lastKNode = lastKNode.Next
        }
    }    
    newHead := lastKNode.Next
    lastKNode.Next = oldTailNode.Next
    oldTailNode.Next = head
    h.Next = newHead
    return h.Next
}

总结

  1. 核心操作:链表基础操作(添加、删除、翻转、头结点运用)是解题根基,贯穿各类题型。
  1. 解题思路:单链表往前倒数,用快慢指针;涉及反转、删除,借助虚拟头节点,提前保存当前位置 k - 1 的节点。
  1. 例题解法
  • 删除倒数第 n 个链表节点:利用快慢指针定位待删节点前驱,实现删除。
  • 删除链表的重复值节点:哈希表统计频次,结合链表删除操作。
  • 旋转链表:转换题意,依据节点位置关系,调整链表结构 。
相关推荐
芜湖xin6 分钟前
【题解-洛谷】P1706 全排列问题
算法·dfs
2302_8097983211 分钟前
【JavaWeb】Docker项目部署
java·运维·后端·青少年编程·docker·容器
zhojiew34 分钟前
关于akka官方quickstart示例程序(scala)的记录
后端·scala
sclibingqing1 小时前
SpringBoot项目接口集中测试方法及实现
java·spring boot·后端
曦月逸霜2 小时前
第34次CCF-CSP认证真题解析(目标300分做法)
数据结构·c++·算法
JohnYan2 小时前
Bun技术评估 - 03 HTTP Server
javascript·后端·bun
周末程序猿2 小时前
Linux高性能网络编程十谈|C++11实现22种高并发模型
后端·面试
ZHOU_WUYI2 小时前
Flask与Celery 项目应用(shared_task使用)
后端·python·flask
海的诗篇_3 小时前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法