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

相关推荐
potato_may1 小时前
第18讲:C语言内存函数
c语言·数据结构·算法
仰泳的熊猫2 小时前
LeetCode:95. 不同的二叉搜索树 II
数据结构·c++·算法·leetcode
Nix Lockhart2 小时前
《算法与数据结构》第七章[算法4]:最短路径
c语言·数据结构·学习·算法·图论
xxxxxxllllllshi2 小时前
Cookie、Session、JWT、SSO,网站与 APP 登录持久化与缓存
java·开发语言·jvm·数据结构·缓存·面试
liu****3 小时前
笔试强训(六)
数据结构·c++·算法
草莓工作室4 小时前
数据结构5:线性表5-循环链表
数据结构·循环链表
1白天的黑夜15 小时前
递归-21.合并两个有序链表-力扣(LeetCode)
c++·leetcode·链表·递归
赵杰伦cpp6 小时前
list的迭代器
开发语言·数据结构·c++·算法·链表·list
胖咕噜的稞达鸭7 小时前
二叉树搜索树插入,查找,删除,Key/Value二叉搜索树场景应用+源码实现
c语言·数据结构·c++·算法·gitee
清风wxy8 小时前
C语言基础数组作业(冒泡算法)
c语言·开发语言·数据结构·c++·windows·算法