链表面试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】

相关推荐
晨晖21 小时前
单链表逆转,c语言
c语言·数据结构·算法
其美杰布-富贵-李3 小时前
HDF5文件学习笔记
数据结构·笔记·学习
LYFlied3 小时前
【每日算法】LeetCode 25. K 个一组翻转链表
算法·leetcode·链表
明洞日记4 小时前
【数据结构手册008】STL容器完全参考指南
开发语言·数据结构·c++
kingmax542120085 小时前
《数据结构C语言:单向链表-链表基本操作(尾插法建表、插入)》15分钟试讲教案【模版】
c语言·数据结构·链表
AI科技星5 小时前
质量定义方程常数k = 4π m_p的来源、推导与意义
服务器·数据结构·人工智能·科技·算法·机器学习·生活
Fine姐5 小时前
数据结构04——二叉树搜索树BST
数据结构
仰泳的熊猫6 小时前
1077 Kuchiguse
数据结构·c++·算法·pat考试
LYFlied6 小时前
【每日算法】LeetCode 19. 删除链表的倒数第 N 个结点
算法·leetcode·链表
阿里巴巴AI编程社区6 小时前
Qoder 提效实战:数据开发工程师用 Qoder 提效50%
数据结构