找出单向链表的倒数第m个元素

简介:
链表节点:
class Node
{
public:
    int        data;
    Node*    next;

public:
    Node(int n) : data(n), next(0)
    {
    }


    Node() : data(0), next(0)
    {
    }


    Node* InsertAfter( int _data )
    {
        Node* newnode = new Node(_data);

        newnode->next = next;
        next = newnode;

        return newnode;
    }

}
;


低效的查找算法:
Node* FindMToLastNode(Node* pHead,  int m)
{
    // 第一次遍历,获取链表的计数
    Node* pCurrent = pHead;
    int nCount = 0;
    while (pCurrent)
    {
        ++nCount;
        pCurrent = pCurrent->next;
    }


    // 防止越界
    if (m > nCount) return 0;

    // 第二遍遍历,获取倒数第m个节点,也就是顺数滴n个节点
    int n = nCount - m + 1;
    nCount = 0;
    pCurrent = pHead;
    while (pCurrent)
    {
        ++nCount;
        if (nCount == n)
        {
            return pCurrent;
        }


        pCurrent = pCurrent->next;
    }


    return 0;
}
这个算法很低效,要循环列表两次,从时间上来说,消耗很大.从空间上,需要3个临时变量,消耗也有点大.


高效的查找算法:
Node* FindMToLastNode(Node* pHead,  int m)
{
    // 查找到第m个元素
    Node* pCurrent = pHead;
    for (int i = 0; i < m; ++i)
    {
        if (pCurrent)
        {
            pCurrent = pCurrent->next;
        }

        else
        {
            return NULL;
        }

    }


    // 一起继续遍历到链表尾部,
    
// 现在pFind和pCurrent之间间隔了m个元素,
    
// 所以,当pCurrent遍历到尾部的时候,
    
// pFind就到了倒数第m个元素的位置上.
    Node* pFind = pHead;
    while (pCurrent)
    {
        pFind        = pFind->next;
        // 间隔m个元素
        pCurrent    = pCurrent->next;
    }


    return pFind;
}
这个算法果然精妙!空间上只需要开销两个临时变量,时间上只需要循环链表一遍,也就是O(n)!
我太笨了,居然没有想到如此绝妙的算法.
目录
相关文章
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
195 1
|
9月前
|
机器学习/深度学习 算法
24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交
1. **两两交换链表中的节点**:通过引入虚拟头结点,使所有节点都能采用统一的交换逻辑,避免对头结点单独处理。 2. **删除链表的倒数第N个节点**:利用双指针技巧,让快慢指针保持N个节点的距离,当快指针到达末尾时,慢指针正好指向待删除节点的前一个节点。 3. **链表相交**:先计算两链表长度并调整起点,确保从相同距离末尾的位置开始遍历,从而高效找到相交节点或确定无交点。 以上方法均在时间复杂度和空间复杂度上进行了优化,适合用于理解和掌握链表的基本操作及常见算法设计思路。
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
302 1
|
9月前
|
存储
203. 移除链表元素,707.设计链表,206. 反转链表
链表是数据结构中的重要概念,包含单链表、双链表和循环链表。单链表每个节点存储数据与下一节点指针;双链表增加上一节点指针;循环链表首尾相连。 **例题解析:** 1. **203. 移除链表元素**:通过遍历链表删除指定值节点,注意处理头节点特殊情况。 2. **707. 设计链表**:实现链表的增删查操作,需理解指针操作逻辑,避免直接修改目标节点。 3. **206. 反转链表**:采用双指针或递归方法改变节点指向,完成链表反转。 以上题目涵盖链表核心操作,掌握后可灵活应对相关问题。
|
存储 Python
Python 实现单向链表,和单向链表的反转
链表是一种数据结构,每个节点存储相邻节点的位置信息。单链表中的节点仅存储下一节点的位置。通过Python实现单链表,定义`ListNode`类并关联节点可创建链表。例如,创建A-&gt;B-&gt;C的链表后,可通过反转函数`reverse`将链表反转为CBA。代码展示了如何实现和操作单链表。
279 6
Python 实现单向链表,和单向链表的反转
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
235 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
存储
【初阶数据结构】深入解析单链表:探索底层逻辑(无头单向非循环链表)(一)
【初阶数据结构】深入解析单链表:探索底层逻辑(无头单向非循环链表)
227 1
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
202 0
|
算法 Java
数据结构与算法学习六:单向环形链表应用实例的约瑟夫环问题
这篇文章通过单向环形链表的应用实例,详细讲解了约瑟夫环问题的解决方案,并提供了Java代码实现。
284 0
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
219 0