链表基础题大全(五):阿里巴巴算法 - 保留有序单链表中的重复元素(只保留一次)

(尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/105694552冷血之心的博客)

这段时间完成了职业生涯第一次跳槽,对算法题目有了一个更深的认识和理解,这里将链表常见的面试题目以及解法补充完善。

链表基础题大全(一)

链表基础题大全(二)

链表基础题大全(三):奇偶链表和旋转链表

链表基础题大全(四):单链表相加 & 复制带随机指针的链表 &判断回文链表

链表基础题大全(五):保留有序单链表中的重复元素(只保留一次)


今天我们来看一个更加阴险狡诈的单链表题目吧,大多数情况下,我们见到的单链表题目都是这样的:单链表删除(Delete)或者去除(Remove)节点面试题总结

也就是说,在一个单链表中,题目会要求我们对重复元素进行一个删除,要不全部删除,要么只保留一个重复元素,或者也可以说删除具有指定val的节点。

我们今天来看一个单链表题目:

给定一个有序链表,保留链表中重复出现的元素,并且只保留一次,如给定链表1->1->1->2->3->3->4. 结果为1->3。请写出一个高效的算法。

思路:

之前我们遇到的大多数题目,基本都是要求删除链表中的重复元素,包括全部删除或者只保留一个重复元素,这个题目刚好相反,将所有的不重复元素删除掉,并且只保留一次重复元素。

因为是有序的单链表,所以我们比较cur和cur.next的value是否相等?如果相等的话,将cur放到将要返回的链表中reHead中,并且需要判断rreHead链表中的最后一个元素reCur是否等于当前节点cur的值,以此来决定是否要将当前节点放入reHead中!

说白了,就是节点的断开和续上的操作!

代码实现如下:


public class Test {
    public static void main(String[] args) {
        ListNode node1 = new ListNode(0);
        ListNode node2 = new ListNode(0);
        ListNode node3 = new ListNode(1);
        ListNode node4 = new ListNode(2);
        ListNode node5 = new ListNode(3);
        ListNode node6 = new ListNode(3);
        ListNode node7 = new ListNode(4);
        ListNode node8 = new ListNode(5);
        ListNode node9 = new ListNode(5);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        node7.next = node8;
        node8.next = node9;

        ListNode resNode = saveDumpNodes(node1);

        while (resNode != null) {
            System.out.println(resNode.val);
            resNode = resNode.next;
        }
    }

    private static ListNode saveDumpNodes(ListNode root) {
        if (root == null || root.next == null) {
            return null;
        }
        boolean flag = false;
        if (root.val == root.next.val) { // 特殊情况判断
            flag = true;
        }

        ListNode reHead = root; // 表示结果链表的头节点
        ListNode reCur = root;  // 表示结果链表的尾节点
        ListNode cur = root;    // 当前正在处理的节点
        while (cur.next != null) {
            if (cur.val == cur.next.val) {   // 判断是否是重复节点
                if (reCur.val != cur.val) {  // 是否可以将当前节点放入结果链表中
                    reCur.next = cur;   // 接下来的代码块是更新reCur和cur的相关逻辑
                    cur = cur.next;     // 主要还是断开和续上各个节点
                    reCur = reCur.next;
                    reCur.next = null;
                    continue;
                }

            }
            cur = cur.next;
        }
        // 是否需要特殊处理
        return flag ? reHead : reHead.next;

    }

}

class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}

总结:

这是阿里巴巴新零售供应链-Java岗位社招面试的算法题目,在遇到的时候,也给笔者造成了一定的困扰,希望对大家有所帮助,如果你有更好的解法,也请告诉我哦~


注意啦,注意啦~

欢迎大家关注我的牛客专栏《Java开发岗面试题全解析》 ,点击图片查看详情。

Java开发岗高频面试题全解析,专栏共计32节,已经全部更新完毕。

专栏分9个模块来对Java岗位面试中的知识点进行解析,包括通用面试技能,Java基础,Java进阶,网络协议,常见框架以及算法,设计模式等。

专栏串点成面的解析每个面试题背后的技术原理,由浅入深,循序渐进,力争让大家掌握面试题目的背后的技术原理,摒弃背题模式的陋习。


如果对你有帮助,记得点赞哈,欢迎大家关注我的博客,关注公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

温柔狠角色

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

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

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

打赏作者

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

抵扣说明:

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

余额充值