合并两个排序链表——牛客offer
题目描述:
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
解题思路:
1、一般看到合并这类的题目就会很自然的想到创建一个新的链表,然后将两个链表根据一定的规则加入到新链表中。所以这里提出第一个比较容易理解的思路:
首先,创建一个新链表。然后,同时遍历两个链表的元素并比较大小,将小的元素首先插入到新链表中,并将小元素的遍历指针后移,大元素的遍历指针不动,就这样依次比较,直至两个链表至少有一个为空。如果有一个链表没有遍历完毕,那么就将该链表剩余的元素全部插入到新链表中。这样就完成了两个链表的合并。
当然,除了正序比较,我们也可以选择倒序比较,先将两个链表压入两个栈,然后依次弹出栈的栈顶元素并比较大小,将大的元素采用头插的方式插入到新链表中。注意:采用栈的时候,新链表的头结点是无法预先确定的,而我们又需要通过头指针完成头插操作,所以我们需要先创建一个新结点newHead作为新链表的头结点,当全部插入完毕后,newHead.next即为新链表的头结点。
2、还有一种方式,相比1会节省一些空间,不需要重新建立一个链表。即从两个链表中随便挑选一个作为被插入的链表。假设我们选择链表1作为合并链表,那么设定两个遍历指针walkNode1与walkNode2,分别指向链表1和链表2,并遍历链表2的元素node2,与链表1当前指针指向的元素node1进行比较
迭代遍历比较:
(1)如果node2.val>node1.val:将链表1指针后移,链表2指针不动
(2)否则:将node2插入到node1前面,继续遍历链表2的元素
注意:虽然我们选取链表1作为被插入链表,但是链表1的头结点不一定是合并后链表的头结点。比如链表2的头结点比链表1小,那么此时就需要将链表2的头结点插入到链表1的头结点之前,但是这是无法做到的,因为我们不知道头结点之前的结点是什么。因此,同思路1的处理方式,我们创建一个新的头结点newHead指向链表1的头结点,这样就可以解决以上提出的问题。
本篇只实现第二种思路,这里举一个例子:
现有链表1{1,3,5},链表2{2,4,6}:
a.初始化遍历指针walkNode与前向指针preNode:
b.迭代:比较walkNode1与walkNode2大小并完成插入和指针的后移
walkNode1.val<walkNode2.val,walkNode1与preNode1指针后移
walkNode1.val>walkNode2.val,walkNode2插入进preNode与walkNode1之间。链表1的preNode1指针后移,链表2的walkNode2指针后移
以此类推·····
完整代码:
class ListNode {
int val;
ListNode next = null; ListNode(int val) {
this.val = val;
}
}
public class mergeList {
public void insertNodes(ListNode preNode,ListNode walkNode){
ListNode startNode=preNode;
while(walkNode!=null){
startNode.next=walkNode;
startNode=startNode.next;
walkNode=walkNode.next;
}
}
public ListNode Merge(ListNode list1,ListNode list2) {
//有一个链表为空,则合并结果为另一个链表
if(list1==null){
return list2;
}
else if(list2==null){
return list1;
}
//将链表1作为被插入的链表(合并后的链表)
ListNode newHead=new ListNode();
newHead.next=list1;
ListNode walkNode1=newHead.next;
ListNode walkNode2=list2;
ListNode preNode1=newHead;
while(walkNode2!=null){
//如果链表1已经遍历结束,可以直接将链表2剩余元素插入到链表1
if(walkNode1==null){
insertNodes(preNode1,walkNode2);
break;
}
//如果链表2当前元素比链表1当前元素大,那么链表1指针后移
if(walkNode2.val>walkNode1.val){
preNode1=walkNode1;
walkNode1=walkNode1.next;
}
//否则,将该元素插入到链表1,链表1的preNode指针和链表2walkNode指针后移
else{
ListNode temp=walkNode2.next;
walkNode2.next=preNode1.next;
preNode1.next=walkNode2;
walkNode2=temp;
preNode1=preNode1.next;
}
}
return newHead.next;
}
}
测试代码:
public static void main(String []args){
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(4);
ListNode node3 = new ListNode(5);
ListNode head2= new ListNode(2);
ListNode node5 = new ListNode(3);
ListNode node6 = new ListNode(6);
head.next = node2;
node2.next = node3;
head2.next = node5;
node5.next = node6;
mergeList merge =new mergeList();
ListNode returnHead=merge.Merge(head,head2);
while (returnHead != null)
{
System.out.println(returnHead.val );
returnHead = returnHead.next;
}
}
合并两个排序链表——牛客offer的更多相关文章
- lintcode:合并两个排序链表
题目: 合并两个排序链表 将两个排序链表合并为一个新的排序链表 样例 给出 1->3->8->11->15->null,2->null, 返回 1->2-& ...
- LintCode-165.合并两个排序链表
合并两个排序链表 将两个排序链表合并为一个新的排序链表 样例 给出 1->3->8->11->15->null,2->null, 返回 1->2->3- ...
- [剑指offer] 14. 链表中倒数第K个节点+翻转+逆序打印+合并两个排序链表 + 链表相交(第一个公共节点) (链表)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 两个指针,起始位置都是从链表头开始,第一个比第二个先走K个节点,当第一个走到链表尾时,第二个指针的位置就是倒数第k个节点.(两指针始终相 ...
- LintCode-165 · 合并两个排序链表-题解
描述:将两个排序(升序)链表合并为一个新的升序排序链表样例 1:输入: list1 = null, list2 = 0->3->3->null输出: 0->3->3-&g ...
- 剑指offer—第三章高质量代码(合并两个排序链表)
题目:输入员两个递增排序的链表,合并这两个链表并使新的链表中的结点仍然是按照递增排序的. 思路:首先,定义两个头节点分别为Head1和Head2的链表,然后比较第一个节点的值,如果是Head1-> ...
- 《剑指offer》面试题17—合并两个排序链表
题目:输入两个递增排顺序的链表,合并这两个链表并使合并后的链表仍是递增排序的. 重点: 1.代码鲁棒性:要判断输入的两个链表都为NULL:其中一个链表为NULL的情况. 2.用递归实现,注意递归的思路 ...
- [剑指Offer] 16.合并两个排序链表
题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. [思路1]递归 /* struct ListNode { int val; struct Lis ...
- 【LeetCode每天一题】Merge Two Sorted Lists(合并两个排序链表)
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...
- 16.合并两个排序的链表 Java
题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题思路 两种解法:递归和非递归 参考代码 /* public class ListNode { ...
随机推荐
- django 快速实现文件上传(四)
继博客(三)实现的, 建两个字段,username 用户存放用户名,headImg 用户存放上传文件的路径. 重新同步数据库: 提示: 这个可能是之前已创建了表中的一条记录,之后模型中增加了一个非空的 ...
- eclipse异常:Exception in thread ""http-bio-8080"-exec-5" java.lang.OutOfMemoryError: PermGen space
用eclipse运行项目,最烦的就是非代码错误.现在这个异常信息,表示的是tomcat启动内存溢出.试过的最简单的办法就是eclipse->project->clean->clean ...
- 介绍 14 个 JavaScript 的框架和库
Javascript 得到了众多的技术领导者的拥护和支持,其中一位就是 WordPress 的作者 Matt Mullenweg , 他表示 WordPress 开发者 应该学习 JavaScript ...
- tensorflow训练中出现nan
问题暂记: 之后看 https://blog.csdn.net/qq_23142123/article/details/80526931 https://www.zhihu.com/question/ ...
- 脚本:将git项目下载到本地并启动
大致思路:从git上clone源代码到本地:使用mvn package将源代码达成war/jar包:将打好的包放到tomcatpath/webapps/下:到tomcatpath/bin/下执行res ...
- 一次galera cluster集群故障节点无法启动问题排查
现象 环境: Server version: 10.0.25-MariaDB-wsrep MariaDB Server, wsrep_25.13.raf7f02e 配置文件: [root@node-2 ...
- java 8 中文API
java 8 中文API 转 https://blog.csdn.net/gao_zhennan/article/details/72871202 java 1.6 帮助文档 中文链接:http:// ...
- [ML] Feature Transformers
方案选择可参考:[Scikit-learn] 4.3 Preprocessing data 代码示范可参考:[ML] Pyspark ML tutorial for beginners 本篇涉及:Fe ...
- Java日志体系(八)最佳实践
java常用日志框架关系 Log4j 2与Log4j 1发生了很大的变化,Log4j 2不兼容Log4j 1. Logback必须配合Slf4j使用.由于Logback和Slf4j是同一个作者,其兼容 ...
- 前端学习(一) html介绍和head标签
HTML 一. HTML 介绍 1. HTML概述:html全称Hyper Text Mackeup Language, 翻译为超文本标记语言, 它不是一种编程语言, 是一种描述性的标记语言, 用于描 ...