数据结构链表力扣例题AC(2)——代码以及思路记录

这篇具有很好参考价值的文章主要介绍了数据结构链表力扣例题AC(2)——代码以及思路记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

AC方法1

struct ListNode* reverseList(struct ListNode* head) {
    if(head == NULL)
        return NULL;

    struct ListNode* n1, *n2, *n3;
    n1 = NULL;
    n2 = head;
    n3 = head->next;

    while(n2)
    {
        n2->next = n1;

        n1 = n2;
        n2 = n3;
        if(n3)
        {
            n3 = n3->next;
        }
        
    }
    return n1;
}

代码思路

观察示例,1->2->3->4->5 ==>> 5->4->3->2->1

要将箭头的方向都旋转,假设从左向右改变,第一步2->1,用两个指针 n1 和 n2 分别指向1和2,使 n2 指向 n1 就可以实现了,但是此时由于 2 之前保存的 3 的地址,现在保存了 1 的地址,3 的地址丢失了,因此在实现变换前,需要先将交换的两个数字后面一位的地址也保存下来,预防这种情况的发生。因为链表的末尾是指向NULL的,因此第一个也需要变为指向NULL,所以第一步将三个指针设置为 n1 = NULL, n2 = head,n3 = head->next。考虑结束条件,如果是 n3 指向空的话,此时 n2 刚指向最后一个元素,最后一个元素依然指向NULL,因此结束条件设置为 n2 指向空更合适。改变链表方向时,将 n2 指向 n1 (n2->next = n1,改变了箭头方向),再将 n1 、n2 和 n3 向前移动(n1 = n2;n2 = n3),但是这里要考虑 n3 向前移动的特殊情况,因为结束条件是 n2 指向空(说明箭头方向都已经完成变换),但是 n2 移动到NULL之前,n3 会先指向NULL,当 n2 指向 NULL的时候,n3也跟着移动就会发生错误(NULL->next是绝对错误的),因此加一个判断,当 n3 已经为空的时候就不移动了。此时原来的最后一个元素是第一个元素,也就是该链表的地址,n1 指向他,返回 n1 地址即可。

AC方法2

struct ListNode* cur, *newhead;
    cur = head;
    newhead = NULL;

    while(cur)
    {
        struct ListNode* next = cur->next;
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    return newhead;

代码思路

联想一下栈的原理,进栈和出栈是不是就顺序相反,因此可以创建一个新的空链表,从原链表第一个节点开始加入新链表,因此需要将头结点的下一个节点存储(因为头结点会保存新链表的节点地址),创建cur指向头结点,新链表由于是空,指向NULL;接着开始向新链表添加,先创建一个新指针保存cur的下一个节点(next = cur->next),然后将原链表第一个移动到新链表里面进行头插(cur->next = newhead,这一步就是相当于头插),然后更新了新链表的头结点后,对应的指向头结点的指针newhead移动指向新的头结点(newhead = cur;)cur回到原链表,指向next保存的新节点。由于cur是添加到新链表以后再回到原链表,因此当cur指向NULL的时候就可以停止了,因此作为while循环条件,最后返回新链表的头结点地址就是变换了顺序的链表的地址了。

链表中倒数第k个结点

输入一个链表,输出该链表中倒数第k个结点。

AC

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    // write code here

    struct ListNode* fast = pListHead;
    struct ListNode* slow = pListHead;

    for(int i = 0; i < k; i++)
    {
        if(fast == NULL)
        {
            return NULL;
        }
        fast = fast->next;
    }
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

代码思路

这道题用快慢指针的方法就非常妙,先简单说说一般思路:先创建一个指针将链表遍历一遍得出链表长度,再用链表长度减去 k 得出正数是第几个,然后输出正数的节点。

但如果使用快慢指针:fast 指针和 slow 指针最开始都指向头结点,先让 fast 指针走 k 个节点,此时 fast 指针和 slow 指针间就有 k 个节点距离,接着让 fast 和 slow 指针同时向前走,这个过程中两个指针之间始终保持着 k 个距离,因此当 fast 指针走到最后的时候,slow 指针正好处于倒数第 k 个。不过有特殊情况需要考虑,就是如果 k 大于了链表节点数,结果是输出空指针,因此在 fast 移动的时候就去检验他会不会等于空,如果 fast 等于空了直接 return NULL,因为k大于链表节点数,那么 i 还没有大于等于 k ,fast 就已经变为 NULL 了。其次还有 k=0 的情况,这时候进不去 for 循环,但是可以进去 while 循环,也就是快慢指针同时走了,fast=NULL 的时候 slow 也为 NULL 了,最后返回 slow 也就是返回空了。

这道题只写快慢指针的方法,有兴趣的实现第一种简单思想的,以练算法为主就不暴力了文章来源地址https://www.toymoban.com/news/detail-831388.html

到了这里,关于数据结构链表力扣例题AC(2)——代码以及思路记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】浅谈数据结构-链表【思路+例题学习】

    🏆今日学习目标: 🍀学习算法-数据结构-链表 ✅创作者:贤鱼 ⏰预计时间:30分钟 🎉个人主页:贤鱼的个人主页 🔥专栏系列:算法 🍁贤鱼的个人社区,欢迎你的加入 贤鱼摆烂团 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中

    2024年01月21日
    浏览(42)
  • 数据结构例题代码及其讲解-顺序表

    静态分配内存及初始化 动态分配内存及初始化 01 对顺序表L进行遍历并输出每个数据元素的数据值 02 假设有一个顺序表L,其存储的所有数据元素均为不重复的正数,查找 L 中值为 e 的数据元素,若找到则返回其下标,若找不到则返回-1。 03 假设有一个顺序表 L,其存储的所有

    2024年02月10日
    浏览(36)
  • 数据结构例题代码及其讲解-栈与队列

    栈Stack 后进先出 ​ 栈的结构体定义及基本操作。 初始化 ​ 这里初始化时是将栈顶指针指向-1,有些则是指向0,因此后续入栈出栈的代码略微有点区别 判断栈是否为空 压栈操作 由于初始时栈顶指针指向-1,因此需要先变化栈顶指针,然后入栈操作; 且当MaxSize为50时候,数

    2024年02月10日
    浏览(42)
  • 数据结构例题代码及其讲解-递归与树

    ​ 树的很多题目中都包含递归的思想 递归 递归包括 递归边界 以及 递归式 即:往下递,往上归 递归写法的特点: 写起来代码较短,但是时间复杂度较高 01 利用递归求解 n 的阶乘。 02 斐波那契数列是满足 F(0)=1,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2)的数列,数列的前几项为 1,1,2,

    2024年02月09日
    浏览(49)
  • 数据结构:队列的链表结构(含完整代码,可复制)

    1.输出队列 2.入队一个元素 3.出队一个元素 5.建立链表队列 6.完整代码

    2024年01月16日
    浏览(44)
  • 数据结构之手撕链表(讲解➕源代码)

    我们在学习过顺序表之后,会发现两点不是很优秀的操作: 1.顺序表的 头插和中间的插入,头删和中间的删除:          需要不断的覆盖数据,时间复杂度是O(n),当我们的顺序表存入100w个数据的时候,花费的时间是非常之多的。 2. 动态开辟空间:         a. 一般动态

    2024年02月08日
    浏览(37)
  • 【数据结构与算法】 - 双向链表 - 详细实现思路及代码

    前几篇文章介绍了怎样去实现单链表、单循环链表, 这篇文章主要介绍 双向链表 以及实现双向链表的步骤,最后提供我自己根据理解实现双向链表的C语言代码 。跟着后面实现思路看下去,应该可以看懂代码,看懂代码后,就对双向链表有了比较抽象的理解了,最后自己再

    2024年02月01日
    浏览(36)
  • 【数据结构】双向链表的增删查改(C 代码实现)

    引入双向链表:关于单链表的问题与讨论 单链表存在的毛病: 因为单链表 只能单向 遍历链表, 对于 前插 这个操作,单链表必 须得找到所需前插节点位置的前一个 ,那么这时就得 从头指针重新遍历一次 链表,会造成时间复杂度大大增加。 没有头节点(哨兵位)无法删除

    2024年02月08日
    浏览(51)
  • 【数据结构与算法】- (带尾指针)单循环链表 - 详细实现步骤及代码(C/C++)

    前三篇文章分别介绍了 “带头结点单链表实现”、“不带头结点单链表实现”、“带头结点单循环链表实现”。 这篇文章主要介绍 带尾指针 的单循环链表以及详细的实现步骤,最后提供我自己根据理解实现带尾指针单循环链表的C语言代码 。跟着后面实现思路看下去,应该

    2024年02月16日
    浏览(38)
  • 【数据结构】线性表 ⑤ ( 双循环链表 | 双循环链表特点 | 双循环链表插入操作处理 | 代码示例 - 使用 Java 实现 双循环链表 )

    \\\" 双循环链表 \\\" 是 在 单循环链表 的基础上 , 在每个 节点 中 , 新增一个 指针 , 指向 该节点 的 前驱节点 ; 双向循环链表 每个 节点 都包含 数据 和 两个指针 , 一个指针指向前一个节点 , 一个指针指向后一个节点 ; 与 单循环链表相比 , 双循环链表 可以在两个方向上遍历整个链

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包