关于链表的题目—leetcode

这篇具有很好参考价值的文章主要介绍了关于链表的题目—leetcode。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第一题:删除链表中的指定节点

问题描述:

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:

输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

题目接口:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteNode(struct ListNode* head, int val){

}

问题解答思路: 

这道题的意思就是要删除链表中的值等于val的节点,但是这道题需要考虑两种情况。

第一种情况就是删除头节点,第二种情况就是删除不是头节点的情况。这两种情况可是不一样的,假如我们把这两种情况混为一谈这道题是不一定能通过的。所以我们要分两种情况来解决这道题。

解法1:分头节点与一般节点两种情况

struct ListNode* deleteNode(struct ListNode* head, int val){
        while(head!=NULL&&head->val==val){//处理头节点的问题
            struct ListNode*temp = head;
            head = head->next;//移动head删掉头节点
            free(temp);
        }
        struct ListNode*temp = head;
        struct ListNode*cur = head->next;//因为头节点已经处理完了,所以再让cur指向head是没有意义的,所以让cur指向第二个节点
        while(cur){
            if(cur->val==val){
             temp->next = cur->next;//删除值为val的节点
             cur = cur->next;//再次移动cur
            }
            else{
                temp = cur;//记录cur的原来位置
                cur = cur->next;//cur向下一位移动
            }

        }
return head;
}

解法2:加一个节点在头节点前面

思路:既然第一种解法要我们处理两种情况,那我们可不可以把这两种解法换成一种解法呢?当然可以,只要我们人为的创建一个节点就可以将将头节点的情况去掉了。

虚拟头节点法:

struct ListNode* deleteNode(struct ListNode* head, int val){
    struct ListNode* dumy = (struct ListNode*)malloc(sizeof(struct ListNode));//使用malloc搞出来一个虚拟节点。
    struct ListNode* cur = head;
    struct ListNode* temp = dumy;
    dumy->next = head;//将dump连接在head的前面,是dumy成为一个头节点
    while(cur){//第一种方法中的普通节点处理法,这次就要从head开始删除了。
        if(cur->val==val){
            temp->next = cur->next;
            cur = cur->next;
            temp = cur;

        }
        else{
            temp = cur;
            cur = cur->next;
        }

    }
head = dumy->next;//返回值是dumy->next。这一点要注意
free(dumy);//释放掉dumy,防止内存泄漏
return head;//返回头节点。

}

解法三:尾插法

对于愚笨的我来说,这种方法是我最难理解的,那我就在这里重点讲解一下吧。

首先来看一下代码:

尾插法代码:

struct ListNode* deleteNode(struct ListNode* head, int val){
    struct ListNode* cur  = head;
    struct ListNode* tail = NULL;
    struct ListNode* newnode = NULL;
    while(cur){
        if(cur->val!=val){
            if(tail == NULL){
                tail =newnode = cur;
                
            }
            else{
                tail->next = cur;
                tail = tail->next;
               
            }
            cur = cur->next;
            tail->next = NULL;
        }
        else{
            struct ListNode*  del = cur;
            cur = cur->next;
            free(del);
        }
       
         
    }
    return newnode;

}

尾插法解法过程演示:

首先我们要明确的是,不论这道题怎么写这道题都有三种情况要处理。即:删除头节点,删除中间节点,删除尾节点。

1.删除头节点:

假如我们的链表是:-3->5->99,要删除的值是-3,也就是要删除头节点

关于链表的题目—leetcode

 现在我们看看代码是如何走的:下面代码是删除头节点时的执行代码

 struct ListNode* cur  = head;
    struct ListNode* tail = NULL;
    struct ListNode* newnode = NULL;
 else{
            struct ListNode*  del = cur;
            cur = cur->next;
            free(del);
        }

这段代码执行以后:

tail,newnode,cur三者与链表的关系就变成这样了:

关于链表的题目—leetcode

然后我们就不用删除头节点了,剩下的节点的处理方式就是下面代码:

 struct ListNode* cur  = head;
    struct ListNode* tail = NULL;
    struct ListNode* newnode = NULL;
    while(cur){
        if(cur->val!=val){
            if(tail == NULL){
                tail =newnode = cur;
                
            }
            else{
                tail->next = cur;
                tail = tail->next;
               
            }
            cur = cur->next;
            tail->next = NULL;
        }

现在,因为tail节点指向空,cur->val!=val。所以执行第二个if语句。

关于链表的题目—leetcode

但是此时tail还是要与cur指向的下一个元素有联系。其实这也可以把tail看作是cur的一个拷贝,既然是拷贝tail指向的下一个节点当然就是cur指向的下一个节点了。

代码

  cur = cur->next;
  tail->next = NULL;

 再来看看这一段代码的示意图:

关于链表的题目—leetcode

在这里可以看到在执行了cur=cur->next的操作以后,将tail的next置空的操作。这是要特别注意的一点。因为这样的操作可以避免野指针的问题。当然还有一点需要注意的就是这两个代码执行顺序的问题。如果先执行tail->next = NULL的操作,再执行cur = cur->next的操作将会导致栈溢出的问题。原因很简单,因为tail与cur一开始指向的是同一块空间,假如先置空tail的next,cur将找不到自己的next。 

最后,执行以下代码:

else{
       tail->next = cur;
       tail = tail->next;
            }
            cur = cur->next;
            tail->next = NULL;

关于链表的题目—leetcode 

 最后再返回newnode,就得到我们想要得到的结果了。

return newnode;

其它的情况这个代码也是可以过的,在这里就不啰嗦了。 

 文章来源地址https://www.toymoban.com/news/detail-424358.html

 

 

到了这里,关于关于链表的题目—leetcode的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Leetcode60天带刷】day04链表——24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交

    Leetcode原题链接: 24. 两两交换链表中的节点  给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 示例 2: 示例 3: 提示: 链表中节点的数目在范围  [0, 100]  内 0 =

    2024年02月07日
    浏览(29)
  • Leetcodes刷题之删除链表的倒数N个结点和删除链表的中间的结点

    吾心信其可行,则移山填海之难,终有成功之日。                           --孙中山 目录 🍉一.删除链表的倒数N个结点 🌻1.双指针 🍁2.求链表的长度 🌸二.删除链表的中间的结点 给你一个链表,删除链表的倒数第  n   个结点,并且返回链表的头结点。 示例 1: 示例

    2024年02月01日
    浏览(32)
  • LeetCode:19. 删除链表的倒数第 N 个结点

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 题目描述 :给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 来源:力扣(LeetCode) 难度: 中等 提示: 链表中结点的数目为 sz 1 = sz = 30 0 = Node.val = 100 1 = n = sz 示例

    2024年02月02日
    浏览(34)
  • 【LeetCode】19. 删除链表的倒数第 N 个结点

    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5] 示例 2: 输入:head = [1], n = 1 输出:[] 示例 3: 输入:head = [1,2], n = 1 输出:[1] 这题直接不会 循环迭代 为什么用 head 代替 dummy 不行? 因为可能存在只有一

    2024年02月07日
    浏览(31)
  • LeetCode | 19. 删除链表的倒数第 N 个结点

    OJ链接 思路: 定义虚拟头节点 dummy 并初始化使其指向 head 然后定义快慢指针 让快指针先走n步 然后一起走 最后删除倒数第n个节点 然后释放虚拟节点 dummy

    2024年02月04日
    浏览(32)
  • LeetCode19:删除链表的倒数第N个结点

    力扣题目链接

    2024年01月21日
    浏览(32)
  • 【Leetcode】19. 删除链表的倒数第N个节点

    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 进阶:你能尝试使用一趟扫描实现吗? 示例 1: 输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5] 示例 2: 输入:head = [1], n = 1 输出:[] 示例 3: 输入:head = [1,2], n = 1 输出:[1] 一开始我的代码: 跑到这一步的时

    2024年02月15日
    浏览(23)
  • leetcode--删除链表的倒数第N个节点(java)

    19 删除链表的倒数第N个节点 -可以测试 题目描述: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点 示例1: 输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5] 示例2: 输入:head = [1], n = 1 输出:[] 示例3: 输入:head = [1,2], n = 1 输出:[1] 提示: 链表中结点的数目为

    2024年02月07日
    浏览(38)
  • 算法每日一题: 删除排序列表中的重复元素2 | 循环 | 链表的删除 | 虚拟节点

    大家好,我是星恒 今天的题目是昨天题目的进化题,他对链表的删除加深了理解。最重要的是学会了对循环中的特殊部分的处理,还有设置虚拟节点的情况 好了,话不多说,我们直接开始 题目:leetcode 82 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点

    2024年01月16日
    浏览(31)
  • day4 两两交换链表中的节点 删除链表的倒数第N个节点 链表相交 环形链表

    - 两两交换链表中的节点     - cur移动的时候,应该后移动俩位,或者说移动到下一操作节点的前一位 - 删除链表的倒数第N个节点      - 因为slow删除元素是要在删除元素的前一位进行删除,所以while ( k--) 移动的fast还不够,还需要再往后移动一位,这样才能让slow指向正确

    2024年02月16日
    浏览(27)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包