当前位置: 首页 > article >正文

力扣83. 删除排序链表中的重复元素(java常规解法 + 建立虚拟头节点)

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

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code

思路

常规解法:一次遍历,每次判断若当前节点值和其下一个节点值,若相等则当前节点指向其下一个节点的下一个节点。
建立虚拟头节点和尾指针(准确来说应该是一种技巧):建立虚拟头节点和尾指针,遍历时当当前指向的节点值和尾指针指向的节点值不同时将其添加到尾指针上。

解题方法

常规解法:

1.循环退出条件为cur != null && cur.next != null(cur为开始定义指向链表头节点并且用于遍历链表的辅助指针);
2.每次判断若当前节点值和其下一个节点值,若相等则当前节点指向其下一个节点的下一个节点;否则直接迭代(cur = cur.next)

建立虚拟头节点和尾指针:

1.建立虚拟头节点,辅助遍历指针指向链表头,尾指针指向建立的虚拟头节点该操作能够较好的解决原始待删除链表头部就存在重复值的情况
2.循环退出条件为辅助遍历指针不为空
3.若辅助遍历指针当前指向的节点值和尾指针指向的节点值不相同,则让尾指针指向该节点,否则正常迭代遍历(实际操作细节看代码)
4.返回虚拟头节点的下一个节点

复杂度

常规解法:

  • 时间复杂度:

O ( n ) O(n) O(n)

  • 空间复杂度:

O ( 1 ) O(1) O(1)

建立虚拟头节点和尾指针:

  • 时间复杂度:

O ( n ) O(n) O(n)

  • 空间复杂度:

O ( 1 ) O(1) O(1)

Code

常规解法:


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //Time Complexity: O(n)
    //Space Complexity: O(1)
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) return null;
        ListNode cur = head;
        //当当前节点和其下一个节点均不为null
        while (cur != null && cur.next != null) {
            if (cur.val == cur.next.val) {
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return head;
    }

}

建立虚拟头节点和尾指针:


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //Time Complexity: O(n)
    //Space Complexity: O(1)
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) return null;
        //建立虚拟头节点
        ListNode dummyNode = new ListNode(-666);
        dummyNode.next = head;
        //建立头指针和尾指针
        ListNode p = head;
        //尾指针指向虚拟头节点
        ListNode tail = dummyNode;
        while (p != null) {
            //先将下一个节点取出
            ListNode nextNode = p.next;
            if (p.val != tail.val) {
                tail.next = p;
                tail = p;
                tail.next = null;
            }
            p = nextNode;
        }
        return dummyNode.next;
    }
        
}

http://www.kler.cn/a/134011.html

相关文章:

  • Webkit 滚动条样式属性
  • C++STL容器——map和set
  • 基于海思soc的智能产品开发(两个图像处理来源)
  • C++单例模式与多例模式
  • 将Excel文件的两个表格经过验证后分别读取到Excel表和数据库
  • 记录使用documents4j来将word文件转化为pdf文件
  • springBoot 配置druid多数据源 MySQL+SQLSERVER
  • sqli-labs关卡20(基于http头部报错盲注)通关思路
  • vite vue3安装element-plus
  • 【开源】基于Vue.js的开放实验室管理系统的设计和实现
  • 【Java 进阶篇】Ajax 入门:打开前端异步交互的大门
  • 【Kingbase FlySync】命令模式:部署双轨并行,并实现切换同步
  • Git 简介及使用
  • 手机,蓝牙开发板,TTL/USB模块,电脑四者之间的通讯
  • mybatis使用xml形式配置
  • c# 设计一个图书管理系统
  • react 手机端 rc-table列隐藏(根据相关条件是否隐藏)、实现图片上传操作
  • MIB 6.S081 System calls(1)using gdb
  • 设计模式-适配器-笔记
  • 算法之路(二)
  • 【NI-DAQmx入门】校准
  • 05 robotFrameWork+selenium2library 一维数组的使用
  • Nodejs 第十九章(pngquant)
  • HTTP Error 500.31 - Failed to load ASP.NET Core runtime
  • 企业微信H5开发遇到的坑
  • vue3 tsx 项目中使用 Antv/G2 实现多线折线图