删除链表重复元素(一题三解)

删除链表重复元素(一题三解)

一、迭代法

public ListNode recursion_deleteDuplicates(ListNode head){
        ListNode dummy = new ListNode();
        dummy.next = head;//不加哑节点的话,就要用注释里那条,我没看懂
        if(head == null){//当前遍历到头了
            return null;
        }else if(head.next == null){//当前遍历到头了
            return head;
        }else{//确保至少有两个节点时
            if(head.val == head.next.val){//head也要被删,包括头在内,所有相同值的都不能要
                ListNode tmp = head;//head.next
                while (tmp != null && tmp.val == head.val){
                    tmp = tmp.next;
                }
                //此时tmp是第一个值与前面一堆不同的,从它开始才有可能保留下来
                dummy.next = recursion_deleteDuplicates(tmp);
                //新的头换上去
//                return deleteDuplicates(tmp);
            }else{//head存活,判断head下一个接什么
                head.next = recursion_deleteDuplicates(head.next);
            }
        }
        return dummy.next;
    }

二、一遍遍历

public ListNode iteration_deleteDuplicates(ListNode head){
        ListNode dummy = new ListNode();
        dummy.next = head;
        if(head == null){//当前遍历到头了
            return null;
        }else if(head.next == null){//当前遍历到头了
            return head;
        }//故技重施
        else{
            ListNode pre = dummy;
            ListNode cur = head;
            while (cur != null){
                while (cur.next !=null && cur.val == cur.next.val){
                    cur = cur.next;
                }//cur走到相同元素的最后一个
                if(pre.next == cur){//说明头节点不用删除,判断下一个节点
                    pre = pre.next;
                    //这样看来的话,是pre遍历了整个数组,cur只是每次遍历决定的下一个便利的位置
                }else{//换头行动,把cur后一个不属于一堆同的换上去
                    pre.next = cur.next;
                    cur = cur.next;
                }
            }
        }
        return dummy.next;
    }

三、记录法(结构复杂,耗时,但想法其实很简单)

//map.getOrDefault:返回指定键映射到的值,如果此映射  不包含  键的映射,则返回 defaultValue 。
public V getOrDefault(Object key, V defaultValue) {
        Node<K,V> e;
        return (e = getNode(key)) == null ? defaultValue : e.value;
    }
public ListNode count_deleteDuplicates(ListNode head){
        //老规矩,这里合并一下
        if(head==null||head.next==null) return head;
        //使用一个map去存储结点出现的次数,大于1的就删除
        ListNode cur=head;
        HashMap<Integer,Integer> map=new HashMap<>();
        List<Integer> l1=new ArrayList<>();
        while(cur!=null){
            map.put(cur.val, map.getOrDefault(cur.val, 0)+1);//有这个键就覆盖
            cur=cur.next;
        }
        Iterator<Map.Entry<Integer, Integer>> entry_itr = map.entrySet().iterator();
        //找到次数大于0的map的key
        while(entry_itr.hasNext()){
            Map.Entry<Integer, Integer> entry = entry_itr.next();
            if(entry.getValue()>1) {
                l1.add(entry.getKey());//l1中存了   重复   的点
            }
        }//最好记住,迭代器的遍历方式,迭代器是不是和哑指针是一个性质
        ListNode pre=new ListNode();
        pre.next=head;
        //pre在哑指针的位置上
        cur=head;
        //开始遍历
        while(cur!=null){
            if(l1.contains(cur.val)){//说明这个cur不可取
                if(cur.val==head.val) head=head.next;//cur是头的话,得换头
                pre.next=cur.next;//不管是不是头,cur废了,pre的下一个指向cur的下一个
            }else{
                pre=cur;//可取,留着,从他开始继续遍历
            }
            cur=cur.next;//pre和head操作完之后,cur循环继续下一个
        }
        return head;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星辰的野望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值