删除链表元素:哨兵节点

删除链表元素:哨兵节点

83. 删除排序链表中的重复元素Ⅰ

题目描述

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次

这是一道标星为简单的题,难度不是很大。需要注意的几点是:

  • 链表已经排好序,这样子的话,寻找重复元素,只要看下一个是否与前一个相等就好了。
  • 还有一点是:删除的元素不会是第一个节点。

代码实现

    public static ListNode deleteDuplicates(ListNode head){
        //已排序的链表
        ListNode currNode = head;
        //如果后一值和前一值相等,前一值的next指向后一值的next
        while(currNode!=null&&currNode.next!=null){
            if(currNode.val==currNode.next.val){
                currNode.next = currNode.next.next;
            }else{
                //不相等的情况,就让前指针向后移
                currNode = currNode.next;
            }
        }
        return head;
    }

复杂度分析

  • 时间复杂度:O(n) ,n是节点个数
  • 空间复杂度:O(1)

203.移除链表元素

题目描述

删除链表中等于给定值val的所有节点。

我的初步想法是:

  • 定义两个前后指针,后一个指针代表当前状态curr,前一个指针代表上一个prev.
  • 如果当前的值为val,就让prev.next=curr.next,向后遍历:curr=curr.next。
  • 这样代表的val值的节点就相应删除。

当然,我并没有考虑要删除的多个元素都出现在头节点的情况,如果考虑这点,哨兵节点的好处就体现出来了。

哨兵节点的利用

当要删除的一个或多个节点位于链表的头部时,可以利用哨兵节点,使链表标准化,即使链表永不为空,永不无头,简化插入和删除的操作。

  • 可以定义一个哨兵节点,作为一个伪头,假设它是sentinel:ListNode sentinel = new ListNode(0);
  • 让它指向“真头”head:sentinel.next = head;
  • 定义两个指针,一个为前向指针prev,一个为当前指针curr。
    • curr的值如果就是指定值,让prev的下一节点指向当前节点的下一系节点。
    • curr的值如果不是指定值,就让代表上一节点的指针prev指向当前指针。
    • curr始终是要向后遍历的。
  • 最后返回sentinel.next。(prev和sentinel指向同一地址,prev已经将链表操作完成)

代码实现

   public ListNode sentinelRemove(ListNode head,int val){
       //创建哨兵节点,指向head
       ListNode sentinel = new ListNode(0);
       sentinel.next = head;
       //定义两个指针,前向指向哨兵节点,当前指向head
       ListNode prev = sentinel;
       ListNode curr = head;
       while(curr!=null){
           if(curr.val == val){
               //当前节点值就是指定值,则让上一个节点的next指向下一个节点
               prev.next = curr.next;
           }else{
               //上一个节点向后移
               prev = curr;
           }
           //遍历下一节点
           curr = curr.next;
       }
       //返回哨兵节点的下一节点
       return sentinel.next;
   }

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

82.删除排序链表中的重复元素Ⅱ

题目描述

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字

同样是删除链表中的重复元素,第一道题是保留一个即可,这个题的意思就是一个不留。需要注意的是:

  • 链表依旧已排序。
  • 删除的节点可能是头节点。

这道题,我们还是可以利用哨兵节点:

代码实现

    public ListNode deleteDuplicates(ListNode head) {
        //创建哨兵节点,指向head
        ListNode sentinel = new ListNode(0);
        sentinel.next = head;
        ListNode prev = sentinel,curr = head;
        //当前位置且下一位置都不为空
        while(curr!=null&&curr.next!=null){
            //如果下一位和这位重复
            if(curr.val == curr.next.val){
                //向后寻找,知道curr为不重复的元素
                int val = curr.val;
                while(curr!=null&&curr.val==val){
                    curr = curr.next;
                }
                //删去重复元素
                prev.next = curr;
            }else{
                //不重复的情况
                //两个指针分别向后移动
                prev = curr;
                curr = curr.next;
            }
        }
        return sentinel.next;
    }

复杂度分析

  • 时间复杂度 :O(n)
  • 空间复杂度 :O(1)

参考链接:
https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode/

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/solution/shan-chu-pai-xu-lian-biao-zhong-de-zhong-fu-yuan-s/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


输出自然数 1 到 n所有不重复的排列,即 n的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
编写一个能够输出“`Hello,World!`”的程序,这个程序常常作为一个初学者接触一门新的编程语言所写的第一个程序,也经常用来测试开发、编译环境是否能够正常工作。

提示:“`Hello,Worl
题目相关 【题目描述】 求10000以内n的阶乘。 【输入】 只有一行输入,整数n(0≤n≤10000)。 【输出】 一行,即n!的值。 【输入样例】 4 【输出样例】 24 分析 首先n的阶乘是从1
题目相关 原题链接:P5461 赦免战俘 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目背景 借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了! 题目描述 现有 $2n
水仙花数 题目描述 输出所有的"水仙花数".所谓"水仙花数"是指这样的一个三位数:其各位数字的立方和等于该数本身。例如:371是
题目描述 奖学金 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文
已知正整数k满足2≤k≤9,现给出长度最大为30位的十进制非负整数c,求所有能整除c的k。
题目相关 题目描述 我们要求找出具有下列性质数的个数(包含输入的正整数 n)。 先输入一个正整数 n(n ≤1000),然后对此正整数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个正整数,
题目相关 题目描述 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且 r ≤n),我们可以简单地将n个元素理解为自然数1,2,…,n从中任取r个数。 现要求你输出所有组合。
题目相关 题目描述 把 m个同样的苹果放在 n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法。(5,1,1 和 1,1,5 是同一种方法) 输入格式 第一行是测试数据的数目 t,以下每行
题目相关 【题目描述】 求两个不超过200位的非负整数的和。 【输入】 有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。 【输出】 一行,即相加后的结果。结果里不能有多余的前导0,即如
请你编一程序实现两种不同进制之间的数据转换。
题目相关 【题目描述】 求两个大的正整数相减的差。 【输入】 共2行,第1行是被减数a,第2行是减数b(a > b)。每个大整数不超过200位,不会有多余的前导零。 【输出】 一行,即所
题目描述 一个数如果恰好等于不包含它本身所有因子之和,这个数就称为"完数"。 例如,6的因子为1、2、3,而6=1ʲʳ,因此6是"完数&amp
题目相关 【题目描述】 任意给定一个正整数N(N≤100),计算2的n次方的值。 【输入】 输入一个正整数N。 【输出】 输出2的N次方的值。 【输入样例】 5 【输出样例】 32 分析 本题考察的是
题目相关 【题目描述】 输入三个整数,整数之间由一个空格分隔,整数是32位有符号整数。把第二个输入的整数输出。 【输入】 只有一行,共三个整数,整数之间由一个空格分隔。整数是32位有符号整数。 【输出
79. 单词搜索 给定一个二维网格和一个单词,找出该单词是否存在于网格中。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母
[toc] 707.设计双向链表 链表简介 链表(LinkedList) 是一种线性表,但不是顺序表,因为它是通过节点直接的相互引用相互联系起来的。 由于不必按顺序存储, 链表在插入和删除的时候可以达
题目描述 784. 字母大小写全排列 给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。 示例: 输入:S = "a1
[toc] Leetcode动态规划【简单题】 动态规划 (Dynamic programming,简称DP),是一种把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划相较于递归,拥有更