链表面试OJ题(1)

今天讲解两道链表OJ题目。

1.链表的中间节点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例

复制代码
输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 

方法1【 双指针】

时间复杂度 :O(N)

思想:两个指针,faster的速度是slow两倍,则当faster走到结尾时,slow则走到链表中间。

易错:循环条件

cs 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode*faster=head;
    struct ListNode*slow=head;
    while(faster && faster->next)//条件没想到
    {
        faster=faster->next->next;
        slow=slow->next;
    }
    return slow;
}

2.移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

示例

复制代码
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

方法1【三指针--无哨兵位】

时间复杂度:O(N)

思想:三个指正,cur负责对比val,tmp负责存储删除元素的下一个元素地址,prve负责存储删除元素的上一个元素地址

易错:

  • 记住prve是cur的前一个元素,那么它从NULL开始
  • 循环条件
  • 记得处理头节点和尾节点
  • 造成野指针的错误❌
cs 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
    struct ListNode*cur=head;
    struct ListNode*prve=NULL;
    while(cur)
    {
        if(cur->val == val)
        {
            struct ListNode*tmp=cur->next;
            free(cur);
            if(prve)
            {
                prve->next=tmp;
            }                                   
            else
            {
                head=tmp;
            }                          
            cur=tmp;
        }

        else
        {
            prve=cur;
            cur=cur->next;
        }
    }
    return head;
                                
}

方法2【双指针---无哨兵位】

cs 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
       struct ListNode*newhead=NULL;
       struct ListNode*tail=NULL;
       struct ListNode*cur=head;
       while(cur)
       {
           if(cur->val != val)
           {
               if(newhead == NULL)
               {
                   newhead=tail=cur;
               }
               else
               {
                   tail->next=cur;
                   tail=tail->next;
               }
               cur=cur->next;
           }
           else
           {
               struct ListNode*tmp=cur->next;
               free(cur);
               cur=tmp;
           }
           if(tail)
           {
               tail->next=NULL;
           }
       } 
       return newhead;          
}

//❌改进

那有哨兵位怎么写呢?

当然,这道题还可以联系前面顺序表(移除val)。

代码---------→【唐棣棣 (TSQXG) - Gitee.com

联系---------→【邮箱:2784139418@qq.com】

相关推荐
夏末秋也凉8 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
王老师青少年编程8 小时前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛
liuyuzhongcc11 小时前
List 接口中的 sort 和 forEach 方法
java·数据结构·python·list
计算机小白一个12 小时前
蓝桥杯 Java B 组之背包问题、最长递增子序列(LIS)
java·数据结构·蓝桥杯
卑微的小鬼13 小时前
数据库使用B+树的原因
数据结构·b树
cookies_s_s13 小时前
Linux--进程(进程虚拟地址空间、页表、进程控制、实现简易shell)
linux·运维·服务器·数据结构·c++·算法·哈希算法
醉城夜风~15 小时前
[数据结构]双链表详解
数据结构
gyeolhada15 小时前
2025蓝桥杯JAVA编程题练习Day5
java·数据结构·算法·蓝桥杯
阿巴~阿巴~15 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
刃神太酷啦17 小时前
堆和priority_queue
数据结构·c++·蓝桥杯c++组