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

删除排序链表的重复元素I和II,多种解法和思考

删除排序链表的重复元素I

https://leetcode.cn/problems/remove-duplicates-from-sorted-list/description/

一个循环就可以了,如果当前节点和下一个节点值一样,当前节点不移动让next后移动一个,如果不一样则当前节点后移。

在这里插入图片描述

一个循环就可以了,如果当前节点和下一个节点值一样,当前节点不移动让next后移动一个,如果不一样则当前节点后移。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null)
            return head;
        ListNode cur = head;
        while(cur.next!=null){
            if(cur.val==cur.next.val)
                cur.next=cur.next.next;
            else
                cur=cur.next;
        }
        return head;
    }
}
删除排序链表的重复元素II

https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/description/

在这里插入图片描述

学习到的新思想:

1、当不想要某个节点时,可以先找到前置节点然后cur.next=cur.next.next,这样子前面一个节点.next就可以跳过这个节点了,不再需要删除节点再定义两个节点了。为什么不能cur=cur.next;cur的空间始终存在,cur.next只是把空间指向了下一个节点罢了。

PS:当前指针不好改内存,.next指向的改变才是关键所在

2、当某个值得节点都不想要的时候,不要每一次都两个节点进行比较,看是不是两个节点的值一样。可以先开一个变量记录下来节点的值,然后再用1,就可以把所有节点全删了

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null) return null;
        ListNode dummyNode = new ListNode(0,head);
        ListNode cur = dummyNode;
        //为什么可以指两次,其实如果不存在.next.next这个节点也不用删掉不是吗
        //这样子的变动是在链表head上面进行的
        //这里有一步很妙,先拿一个变量记录下来当前节点,然后就可以直接抛弃当前所有
        //节点,不要在两个节点进行比较
        while(cur.next!=null&&cur.next.next!=null){
            int val = cur.next.val;
            if(cur.next.val==cur.next.next.val)
                while(cur.next!=null&&cur.next.val==val)
                    cur.next=cur.next.next;                
            else
                cur = cur.next;
        }
        return dummyNode.next;
    }
}

自己的写法,单循环双节点计数法,先得到前面一个节点和当前节点,然后找到计数为1并且前后两个节点值不一样的位置,双节点再移动,又臭又长。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null) return null;
        //可能会有表头节点全部删除完了的情况,我们依旧采用虚拟节点的写法
        ListNode dummyNode = new ListNode(0,head);
        ListNode pre = dummyNode;
        ListNode cur = dummyNode.next;
        //删除节点,让pre指向下一个满足条件的节点即可
        int flag = 1;
        //计数器flag为1时候就可以赋值了
        while(cur.next!=null){
            if(cur.val==cur.next.val){
                flag++;
                cur.next=cur.next.next;
            }
            else{ 
                if(flag==1){
                    pre.next=cur;
                    cur=cur.next;
                    pre=pre.next;   
                }
                else{
                    cur=cur.next;
                    flag=1;  
                }
            }
        }
        if(flag==1) pre.next=cur;
        else pre.next=null;
        return dummyNode.next;
    }
}

优化了一下过程:

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null) return null;
        ListNode dummyNode = new ListNode(0,head);
        ListNode pre = dummyNode;
        ListNode cur = head;
        while(cur!=null&&cur.next!=null){
            if(cur.val==cur.next.val){
                int val = cur.val;
                while(cur!=null&&cur.val==val)
                    cur=cur.next;
            }
            else{
                pre.next=cur;
                pre=pre.next;
                cur=cur.next;
            }
        }
        pre.next=cur;
        return dummyNode.next;
    }
}

http://www.kler.cn/news/149856.html

相关文章:

  • 拼多多发布Q3财报,Temu成第二增长引擎
  • harmonyos应用开发者高级认证考试部分答案(2)
  • 蓝桥杯day02——第三大的数
  • 线性表之链式表
  • 网工内推 | 中高级网工,IE认证优先,带薪年假,五险一金
  • Windows如何启动MySQL
  • [Linux] linux防火墙
  • 科普 | 隧道代理IP,简化操作提升安全性
  • vue3+vite打包自动生成dist.zip文件
  • JVM
  • 智能合约安全漏洞与解决方案
  • Unity 关于Input类的使用
  • 惠威M200MKII音箱拆机
  • 手摸手Element-ui组件化开发
  • 【C/C++】常见模拟题题解
  • React 和 Vue 在技术层面有哪些区别?
  • JSON.stringify,JSON.parse
  • Linux下文件操作函数
  • 【Linux】 sudo命令使用
  • 每日一题(LeetCode)----哈希表--两数之和
  • ArkUI开发进阶—@Builder函数@BuilderParam装饰器的妙用与场景应用【鸿蒙专栏-05】
  • el-table合并行
  • SecureCRT -- 使用说明
  • 【Apifox】测试工具自动编写接口文档
  • ubuntu系统进入休眠后cuda初始化报错
  • 【Redis基础】Redis基本的全局命令
  • 一文详解Python中常用数据类型
  • render函数举例
  • vue中下载文件后无法打开的坑
  • Linux 下命令行启动与关闭WebLogic的相关服务