题目描述:

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

解题思路:

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的更多相关文章

  1. lintcode:合并两个排序链表

    题目: 合并两个排序链表 将两个排序链表合并为一个新的排序链表  样例 给出 1->3->8->11->15->null,2->null, 返回 1->2-& ...

  2. LintCode-165.合并两个排序链表

    合并两个排序链表 将两个排序链表合并为一个新的排序链表 样例 给出 1->3->8->11->15->null,2->null, 返回 1->2->3- ...

  3. [剑指offer] 14. 链表中倒数第K个节点+翻转+逆序打印+合并两个排序链表 + 链表相交(第一个公共节点) (链表)

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路:  两个指针,起始位置都是从链表头开始,第一个比第二个先走K个节点,当第一个走到链表尾时,第二个指针的位置就是倒数第k个节点.(两指针始终相 ...

  4. LintCode-165 · 合并两个排序链表-题解

    描述:将两个排序(升序)链表合并为一个新的升序排序链表样例 1:输入: list1 = null, list2 = 0->3->3->null输出: 0->3->3-&g ...

  5. 剑指offer—第三章高质量代码(合并两个排序链表)

    题目:输入员两个递增排序的链表,合并这两个链表并使新的链表中的结点仍然是按照递增排序的. 思路:首先,定义两个头节点分别为Head1和Head2的链表,然后比较第一个节点的值,如果是Head1-> ...

  6. 《剑指offer》面试题17—合并两个排序链表

    题目:输入两个递增排顺序的链表,合并这两个链表并使合并后的链表仍是递增排序的. 重点: 1.代码鲁棒性:要判断输入的两个链表都为NULL:其中一个链表为NULL的情况. 2.用递归实现,注意递归的思路 ...

  7. [剑指Offer] 16.合并两个排序链表

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. [思路1]递归 /* struct ListNode { int val; struct Lis ...

  8. 【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 ...

  9. 16.合并两个排序的链表 Java

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题思路 两种解法:递归和非递归 参考代码 /* public class ListNode { ...

随机推荐

  1. java 网络文件下载(并命中文名)

    public void download(HttpServletRequest request, HttpServletResponse response){ //获取服务器文件 String fil ...

  2. Mac 下python3 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法

    原文:http://blog.yuccn.net/archives/625.html python3.6下使用urllib 的request进行url 请求时候,如果请求的是https,请求可以会出现 ...

  3. 用HQL自己写了个update!!!

    原来代码: public void updateSj(String jsly, Integer zu,String sj) { if (!StringUtils.isBlank(jsly)&& ...

  4. pdnovel 看书 读书 听书

    pdnovel剖度小说是discuz的阅读插件,这里分享一下阅读的一些技巧. 看书 点击或手机输入 http://txt.xlongwei.com 即可进入阅读首页,内容分书book.卷volume. ...

  5. VMware配置NAT方式下的静态ip

    一.VMware上NAT模式工作原理 原理图如下: 说明: 1.虚拟主机与本地主机通信时,直接通过虚拟交换机访问(不管是虚拟主机的ip是静态ip还是动态分配的ip) 2.虚拟主机与外网通信时,虚拟主机 ...

  6. Difference between C# compiler version and language version

    Difference between C# compiler version and language version     As nobody gives a good enough answer ...

  7. 用PHP自带函数对二维数组进行排序

    经常会面临这样的需求,虽然有时候我们可以在数据库查询的时候,直接对数据进行排序,但还是无法满足日益复杂的业务需求. 这里边会用到两个函数 一个是array_column()函数,这个函数接受三个参数. ...

  8. LC 638. Shopping Offers

    In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, there are ...

  9. 深度学习之GAN对抗神经网络

    1.结构图 2.知识点 生成器(G):将噪音数据生成一个想要的数据 判别器(D):将生成器的结果进行判别, 3.代码及案例 # coding: utf-8 # ## 对抗生成网络案例 ## # # # ...

  10. Python之滑动窗口

    需求 对于一个数组array = ["n","v","l","f",...,"y","c& ...