zoukankan      html  css  js  c++  java
  • 删除链表元素:哨兵节点

    删除链表元素:哨兵节点

    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/

  • 相关阅读:
    一个php soap的错误记录
    Android 开发有哪些新技术出现?
    每个PHP开发者都应该看的书
    30 个 PHP 的 Excel 处理类
    PHP Session可能会引起并发问题
    PHP代码优化技巧大盘点
    分析和解析PHP代码的7大工具
    关于 PHP 7 你必须知道的五件事
    PHP也20岁了
    PHP高级特性二之文件处理
  • 原文地址:https://www.cnblogs.com/summerday152/p/12215734.html
Copyright © 2011-2022 走看看