两者思路对比:

直接操作:因为传入的是两个有序的链表,所以说我就直接以其中一个链表为基准,与另外一个链表比较,只将比返回值链表的最后一个记录的值大的插入,不将等值的插入,理论时间复杂度为O(n)

Set操作:将所有的节点取出放入TreeSet有序集合中,最后生成一个链表返回,理论时间复杂度为O(2n)

直接操作步骤示意图:

以{1,3,5}{1,2,4,5,5,6}为例

  1. 先取个返回值链表的表头,并将该链表作为基准链表,比较第一个值小的为基准链表,相同就取第一个
    返回值链表:1->null
    基准链表:3->5->null
    非基准链表:1->2->4->5->5->6->null
  2. 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值相同就丢弃
    返回值链表:1->null
    基准链表:3->5->null
    非基准链表:2->4->5->5->6->null
  3. 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
    返回值链表:1->2->null
    基准链表:3->5->null
    非基准链表:4->5->5->6->null
  4. 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
    返回值链表:1->2->3->null
    基准链表:5->null
    非基准链表:4->5->5->6->null
  5. 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
    返回值链表:1->2->3->4->null
    基准链表:5->null
    非基准链表:5->5->6->null
  6. 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
    返回值链表:1->2->3->4->5->null
    基准链表:null
    非基准链表:5->5->6->null
  7. 其中一个链表为null之后直接只遍历另外一个链,因为要去重,所以要遍历完,取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值相同就丢弃
    返回值链表:1->2->3->4->5->null
    基准链表:null
    非基准链表:5->6->null
  8. 取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值相同就丢弃
    返回值链表:1->2->3->4->5->null
    基准链表:null
    非基准链表:6->null
  9. 取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值不同就保留,此时两个链表都为null则结束
    返回值链表:1->2->3->4->5->6null
    基准链表:null
    非基准链表:null

对于Set操作的算法则不展开

自己写的比较的算法:

import java.util.*;

public class Main {

    public static void main(String[] args) {
Node headOne = new Node(-1);
Node headTwo = new Node(-1);
Node p1 = headOne;
Node p2 = headTwo;
int[] one = new int[10000];
int[] two = new int[15000];
Random rm = new Random();
for (int i = 0; i < 10000; i++){
one[i] = rm.nextInt(500);
}
for (int i = 0; i < 15000; i++){
two[i] = rm.nextInt(500);
}
Arrays.sort(one);
Arrays.sort(two);
for (int i = 0; i < one.length; i++){
Node node = new Node(one[i]);
p1.next = node;
p1 = p1.next;
}
for (int i = 0; i < two.length; i++){
Node node = new Node(two[i]);
p2.next = node;
p2 = p2.next;
} long start = System.nanoTime();
Node re = change(headOne.next, headTwo.next);
long end = System.nanoTime(); System.out.println("直接操作:" + (end - start) + "ns"); start = System.nanoTime();
Node reSet = changeSet(headOne.next, headTwo.next);
end = System.nanoTime();
System.out.println("Set时间: " + (end - start) + "ns");
} private static Node change(Node headOne, Node headTwo){
//空值判断
if (headTwo == null){
return headOne;
}
if (headOne == null){
return headTwo;
} //返回首元素较小的头结点, 先取一个节点为基准
Node reHead = headOne.data <= headTwo.data? headOne: headTwo;
Node p2 = headOne.data >= headTwo.data? headTwo: headOne; //另一条链
Node pre = reHead; //上一个节点
Node p1 = reHead.next; //当前链 while(p1 != null && p2 != null){
if(p1.data <= p2.data){
if (p1.data == p2.data){
p2 = p2.next;
}
if (p1.data != pre.data){
pre = pre.next;
p1 = p1.next;
}else{
pre.next = p1.next; //跳过该相同节点
p1 = p1.next;
}
}else{
if (p2.data != pre.data){
pre.next = p2;
p2 = p2.next;
pre = pre.next;
pre.next = p1;
}else {
p2 = p2.next;
}
}
} Node now = p1 != null? p1: p2;
pre.next = now;
while(now!= null){
if (pre.data == now.data){
now = now.next;
pre.next = now;
}else{
pre = pre.next;
now = now.next;
}
}
return reHead;
} private static Node changeSet(Node headOne, Node headTwo){
Node re = new Node(-1);
Node head = re;
TreeSet<Node> s = new TreeSet<>();
while(headOne != null){
s.add(headOne);
headOne = headOne.next;
}
while(headTwo != null){
s.add(headTwo);
headTwo = headTwo.next;
}
Iterator iterator = s.iterator();
while (iterator.hasNext()){
Node p = (Node) iterator.next();
Node tmp = new Node(p.data);
head.next = tmp;
head = head.next;
}
return re.next;
}
} class Node implements Comparable{
int data;
Node next; public Node(int data){
this.data = data;
} @Override
public int compareTo(Object o) {
Node t = (Node)o;
if (this.data > t.data){
return 1;
}else if (this.data == t.data){
return 0;
}else {
return -1;
}
}
}

实现代码

然后运行的时间截图:

如有错误和不足,望指正
千里之行,始于足下

去重合并两个有序链表之直接操作和Set集合操作的更多相关文章

  1. 【LeetCode题解】21_合并两个有序链表

    目录 21_合并两个有序链表 描述 解法一:迭代 思路 Java 实现 Python 实现 解法二:递归 思路 Java 实现 Python 实现 21_合并两个有序链表 描述 将两个有序链表合并为一 ...

  2. leetcode 21 Merge Two Sorted Lists 合并两个有序链表

    描述: 合并两个有序链表. 解决: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (!l1) return l2; if (!l2) ...

  3. Leecode刷题之旅-C语言/python-21.合并两个有序链表

    /* * @lc app=leetcode.cn id=21 lang=c * * [21] 合并两个有序链表 * * https://leetcode-cn.com/problems/merge-t ...

  4. LeetCode初级算法--链表02:合并两个有序链表

    LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...

  5. <每日 1 OJ> -LeetCode 21. 合并两个有序链表

    题目: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4输出:1->1-> ...

  6. 算法练习之合并两个有序链表, 删除排序数组中的重复项,移除元素,实现strStr(),搜索插入位置,无重复字符的最长子串

    最近在学习java,但是对于数据操作那部分还是不熟悉 因此决定找几个简单的算法写,用php和java分别实现 1.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两 ...

  7. LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)

    21. 合并两个有序链表 21. Merge Two Sorted Lists 题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. LeetCode ...

  8. leecode刷题(23)-- 合并两个有序链表

    leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...

  9. LeetCode_21.合并两个有序链表

    LeetCode_21 LeetCode-21.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回. 新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...

随机推荐

  1. MySQL-EXPLAIN执行计划Extra解释

    EXPLAIN命令输出的列中Extra字段可选值较多,这里单独说一下. 该Extra列 EXPLAIN输出包含MySQL解决查询的额外信息.以下列表说明了此列中可能出现的值.每个项目还指示JSON格式 ...

  2. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. 颜色下拉菜单(combox)

    using System; using System.Drawing; using System.Collections; using System.ComponentModel; using Sys ...

  4. 【原】iOS查找私有API

    喜接新项目往往预示的会出一堆问题.解决问题的同时往往也就是学到更多东西的时候,这也许就是学习到新东西最直接最快速的方法吧! 小编经过努力,新项目终于过测试了,可是被苹果大大给拒了,好苦啊,最近的审核真 ...

  5. Tomcat源码分析 (十)----- 彻底理解 Session机制

    Tomcat Session 概述 首先 HTTP 是一个无状态的协议, 这意味着每次发起的HTTP请求, 都是一个全新的请求(与上个请求没有任何联系, 服务端不会保留上个请求的任何信息), 而 Se ...

  6. 讲解开源项目:功能强大的 JS 文件上传库

    本文作者:HelloGitHub-kalifun HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...

  7. JavaScript数组方法大全(第一篇)

    数组方法大全(第一篇) 注意:第一次写博客有点小紧张,如有错误欢迎指出,如有雷同纯属巧合,本次总结参考书籍JavaScript权威指南,有兴趣的小伙伴可以去翻阅一下哦 join()方法 该方法是将数组 ...

  8. BeanUtils开发包的使用

    对内省技术有了一定的了解之后,我们就可以来学习一下BeanUtils开发包的使用了. 我们先假设一个情景,有一个JSP文件,如果要将该JSP文件中表单数据封装到Servlet文件应该怎么办?此时方法显 ...

  9. Oracle笔记_基础

    1 登录启动 sqlplus / as sysdba #以管理员方式登录 sqlplus 用户名/密码 #本地登录 sqlplus 用户名/密码@//主机IP/实例名(默认orcl) #远程登录 sq ...

  10. CAP 2.6 版本发布通告

    前言 今天,我们很高兴宣布 CAP 发布 2.6 版本正式版.同时我们也很高兴的告诉你 CAP 在 GitHub 已经突破了3000 Star. 自从上次 CAP 2.5 版本发布 以来,已经过去了几 ...