算法17: 删除排序链表中的重复元素(升序链表去重)

一、需求

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]

输出:[1,2]

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

提示:

  • 链表中节点数目在范围 [0, 300] 内
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序 排列

二、思路图

示例给出的链表示意图如下:

在这里插入图片描述

接着定义变量cur指向链表的头结点,表示当前考察的结点。

在这里插入图片描述

首先,看下cur指向的结点和其后一个结点的值是否相等,如果相等则表示其后一个结点需要删除。

在这里插入图片描述

具体方法是将cur指向的结点的后继指针,指向其下一个结点的下一个结点。这样就将重复结点删除了

在这里插入图片描述

如下图,就是去除重复结点1之后,链表的结构。

在这里插入图片描述

这时cur所指向的结点的下一个结点的值是2,与cur所指向的结点值不同。
在这里插入图片描述

因此,不需要去重,这时将cur指向下一个结点,继续考察。这时,cur所指向的结点之后,没有其它结点,因此去重结束。

在这里插入图片描述

三、代码

创建链表类

ListNode.java

import cn.hutool.core.util.StrUtil;

/**
 * 链表类
 *
 * @author 王子威
 * @date 2021/4/21
 */
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; }

    @Override
    public String toString()
    {
        ListNode ln = this;
        StringBuilder sb = new StringBuilder();

        while(ln != null){
            if (StrUtil.isEmpty(sb))
            {
                sb.append("[" + ln.val);
            }
            else
            {
                sb.append("," + ln.val);
            }
            ln = ln.next;
        }
        sb.append("]");
        return sb.toString();
    }
}

测试接口

/**
 * 入口
 *      83. 删除排序链表中的重复元素
 *      1.创建升序链表
 * 输入:
 *      ListNode head = 1 -> 1 -> 2;
 * 输出:
 *      a.toString() = [1,2]
 * 解释:
 *      因为升序所以遇到下一个不同的值就是链接的地点
 *      我这里并未优化成上面概念
 *      这里的算法是:如果相同直接链接到下个节点,不然就直接复制临时值到下个节点
 */
@Test
public void suanfa17()
{
    // 创建升序链表
    ListNode head = new ListNode(1);
    head.next = new ListNode(1);
    head.next.next = new ListNode(2);

    // 调用方法
    ListNode a = this.deleteDuplicates(head);

    // 这里重写了toString
    System.out.println("a.toString() = " + a.toString());
}

调用方法:删除排序链表中的重复元素(链表去重)

/**
 * 删除排序链表中的重复元素(链表去重)
 *
 * @param head
 * @return
 */
public ListNode deleteDuplicates(ListNode head) {
    // 如果链表为空就直接返回null
    if (head == null ) return null;
    // 不为空,复制头结点到临时节点
    ListNode temp = head;

    // 如果下一个节点不为空
    while(temp.next != null)
    {
        // 临时节点值 = 下个节点的值
        if(temp.val == temp.next.val)
        {
            // 将临时节点的链接到下下个节点上
            temp.next = temp.next.next;
        }
        else
        {
            // 否则将下个节点的值赋值给临时节点(因为节点不同)
            temp = temp.next;
        }
    }
    // 返回头节点
    return head;
}

作者:王子威

四、总结

  • 学习了删除排序链表中的重复元素(链表去重)算法
  • 测试用例废了点功夫,看来需要学习的还有很多
  • 创建链接方案
  • 获取链表的值
  • 链表只要返回头结点,我们就可以根据头结点的地址获取下个节点了
  • 算法兴趣+1 总:17
  • 加强了对算法的分析能力
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值