去重合并两个有序链表之直接操作和Set集合操作
两者思路对比:
直接操作:因为传入的是两个有序的链表,所以说我就直接以其中一个链表为基准,与另外一个链表比较,只将比返回值链表的最后一个记录的值大的插入,不将等值的插入,理论时间复杂度为O(n)
Set操作:将所有的节点取出放入TreeSet有序集合中,最后生成一个链表返回,理论时间复杂度为O(2n)
直接操作步骤示意图:
以{1,3,5}{1,2,4,5,5,6}为例
- 先取个返回值链表的表头,并将该链表作为基准链表,比较第一个值小的为基准链表,相同就取第一个
返回值链表:1->null
基准链表:3->5->null
非基准链表:1->2->4->5->5->6->null - 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值相同就丢弃
返回值链表:1->null
基准链表:3->5->null
非基准链表:2->4->5->5->6->null - 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
返回值链表:1->2->null
基准链表:3->5->null
非基准链表:4->5->5->6->null - 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
返回值链表:1->2->3->null
基准链表:5->null
非基准链表:4->5->5->6->null - 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
返回值链表:1->2->3->4->null
基准链表:5->null
非基准链表:5->5->6->null - 继续下一步后的链表,这一步中,取两个链表中的小值尝试插入,但是发现与返回值链表末端值不同就插入
返回值链表:1->2->3->4->5->null
基准链表:null
非基准链表:5->5->6->null - 其中一个链表为null之后直接只遍历另外一个链,因为要去重,所以要遍历完,取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值相同就丢弃
返回值链表:1->2->3->4->5->null
基准链表:null
非基准链表:5->6->null - 取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值相同就丢弃
返回值链表:1->2->3->4->5->null
基准链表:null
非基准链表:6->null - 取非基准链表中的一个值尝试插入,但是发现与返回值链表末端值不同就保留,此时两个链表都为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集合操作的更多相关文章
- 【LeetCode题解】21_合并两个有序链表
目录 21_合并两个有序链表 描述 解法一:迭代 思路 Java 实现 Python 实现 解法二:递归 思路 Java 实现 Python 实现 21_合并两个有序链表 描述 将两个有序链表合并为一 ...
- leetcode 21 Merge Two Sorted Lists 合并两个有序链表
描述: 合并两个有序链表. 解决: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (!l1) return l2; if (!l2) ...
- Leecode刷题之旅-C语言/python-21.合并两个有序链表
/* * @lc app=leetcode.cn id=21 lang=c * * [21] 合并两个有序链表 * * https://leetcode-cn.com/problems/merge-t ...
- LeetCode初级算法--链表02:合并两个有序链表
LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...
- <每日 1 OJ> -LeetCode 21. 合并两个有序链表
题目: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4输出:1->1-> ...
- 算法练习之合并两个有序链表, 删除排序数组中的重复项,移除元素,实现strStr(),搜索插入位置,无重复字符的最长子串
最近在学习java,但是对于数据操作那部分还是不熟悉 因此决定找几个简单的算法写,用php和java分别实现 1.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两 ...
- LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)
21. 合并两个有序链表 21. Merge Two Sorted Lists 题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. LeetCode ...
- leecode刷题(23)-- 合并两个有序链表
leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...
- LeetCode_21.合并两个有序链表
LeetCode_21 LeetCode-21.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回. 新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...
随机推荐
- Python3源代码编译安装
Python3源代码编译安装 安装必要工具 yum-utils ,它的功能是管理repository及扩展包的工具 (主要是针对repository) $ sudo yum install yum-u ...
- 60701BMP彩色图像转化为灰度及二值图像
1 概述 多媒体技术是一门综合了多种学科的新技术,其涉及到计算机科学与技术.通信和网络技术.人工智能技术.微电子技术.数字信号处理.图形处 理技术.声像技术等诸多学科.许多新技术的不断出现和体验,带给 ...
- Fabric项目学习总结
1.Hyperledger Fabric的基本架构 2.PKI机制
- React中控制台警告
1.dll_lib.js:1 Warning: bind(): You are binding a component method to the component. React does this ...
- 表结构查询 Sql
select row_number() over(order by a.column_id) rownumber, a.name, case ),a.),a.scale) +')' ),a.max_l ...
- appium输入法踩坑解决方案-----中文乱码及输入法搜索无法点击
一.appium1.7.1 遇到的坑: 1. 在写安卓的搜索用例脚本时,发现输入内容后,搜索出现在输入法键盘原来的确认位置,定位不到手机自带输入法的"搜索"键: 2. 传入中文搜索 ...
- 上个月,我赚了2W外快。。。
前段时间和室友一起给某个公司做了一个管理系统,每个人分2W多.这里和大家分享一下做完项目后一点点感受,想到啥就说点啥. 核心竞争力 两个月就挣了2W块,挣了我爸妈两个人一年的收入,每天还贼辛苦,披星戴 ...
- js全选与取消全选
实现全选与取消全选的效果 要求1(将军影响士兵):点击全选按钮,下面的复选框全部选中,取消全选按钮,下面的复选框全部取消 思路:复选框是否被选中,取决于check属性,将全选按钮的check属性值赋值 ...
- 一文了解Python常见的序列化操作
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...
- 深度学习环境搭建部署(DeepLearning 神经网络)
工作环境 系统:Ubuntu LTS 显卡:GPU NVIDIA驱动:410.93 CUDA:10.0 Python:.x CUDA以及NVIDIA驱动安装,详见https://www.cnblogs ...