剑指offer——合并链表
来源:互联网 发布:最基本的网络拓扑结构 编辑:程序博客网 时间:2024/06/13 18:38
1. 问题描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
2. 解决方法
合并链表应该是数据结构里最经典的一道题目。两个链表合并,当然是要一次对比两个链表开头谁更小,谁就当做新的头,然后依次类推下去。
2.1 level1
还记得当时不是用递归写的,一点一点合并的。现在知道怎么用递归了,就用递归写一个吧。代码看起来是真的挺简洁的。
public static ListNode Merge2(ListNode list1,ListNode list2) { if(list1==null){ return list2; } if(list2==null){ return list1; } //如果list1比2小于等于 if(list1.val<=list2.val){ list1.next=Merge2(list1.next, list2); return list1; } else{ list2.next=Merge2(list1, list2.next); return list2; } }
2.2 level2
这时候可能会出现这样一个问题,这时候每次合并都是一个一个合并,一个一个递归,可不可以批量递归呢?比如如果遇到这样的两个链表:
A={1,2,3,8,9,10},B={4,5,6,7,11,12,13}。
于是我们要做进一步改进,算法如下所示:
public static ListNode Merge3(ListNode list1,ListNode list2) { if(list1==null){ return list2; } if(list2==null){ return list1; } if(list1.val<=list2.val){ ListNode temp=list1; ListNode pre=null; //如果list1比2小于等于 while(temp.val<=list2.val){ //如果是最后一个 if(temp.next==null){ temp.next=list2; return list1; } //否则记录上一个结点。 pre=temp; temp=temp.next; } pre.next=Merge3(temp, list2); return list1; } else{ ListNode temp=list2; ListNode pre=null; //如果list2比1小于等于 while(temp.val<=list1.val){ //如果是最后一个 if(temp.next==null){ temp.next=list1; return list2; } //否则记录上一个结点。 pre=temp; temp=temp.next; } pre.next=Merge3(temp, list1); return list2; } }
2.3 level3
但是这样对于小数据量的还好说,对于大数据量的链表来讲,递归就是噩梦啊。因此还是要写非递归的程序。如下所示:
public static ListNode Merge(ListNode list1,ListNode list2) { if (list1 ==null) return list2; if (list2 ==null) return list1; ListNode head = null; ListNode tmp= null; if (list1.val < list2.val) { head = list1; list1 = list1.next; } else { head = list2; list2 = list2.next; } tmp = head; //都没剩的话 while (list1 != null && list2 != null) { if (list1.val < list2.val) { tmp.next = list1; list1 = list1.next; tmp = tmp.next; } else { tmp.next = list2; list2 = list2.next; tmp = tmp.next; } } //如果还有剩的 while (list1 != null || list2 != null) { if (list1 ==null && list2 != null) { tmp.next = list2; list2 = list2.next; tmp = tmp.next; } if (list2 ==null && list1 != null) { tmp.next = list1; list1 = list1.next; tmp = tmp.next; } } return head; }
事实证明,在极端情况下,level2可以比level1和level3快上一个数量级。但是,level1和level2的递归在长链表中,容易出现StackOverFlow的情况。因此非递归的手段也应该掌握。
3. 一点思考
同样的问题,我们有时候喜欢递归的,有时候喜欢非递归的。这完全取决于问题的具体情况。就编码人员而言,当然更喜欢递归的,因为这样代码逻辑清晰。但是这并不是简化了程序,只是简化了程序员这面的工作,对于编译器来讲,将是沉重的负担。因此也应当平衡一下两方面的工作量,这样才能达到效率最高。
0 0
- 剑指offer——合并链表
- 《剑指offer》——合并两个排序的链表
- 《剑指offer》——合并两个排序的链表
- 剑指Offer——有序链表的合并
- 剑指offer——合并两个排序的链表
- 合并两个排序的链表——剑指offer
- 剑指offer——合并两个排序的链表
- 剑指offer——两个合并排序的链表
- 剑指Offer——合并两个排序的链表
- 剑指offer—合并两个排序的链表
- 剑指offer(16)—合并两个排序的链表
- 剑指offer—合并两个排序的链表
- 剑指offer-合并链表
- 剑指offer 合并链表
- 剑指offer--合并两个递增链表
- 剑指Offer-17-合并有序链表
- 剑指offer-合并排序链表
- 剑指offer----合并两个有序链表
- 第一个jsp
- 初始化项目——快捷键
- 二叉树的递归和非递归前、中、后序遍历
- c++的浅复制与深复制
- HDU5631 Rikka with Graph
- 剑指offer——合并链表
- set与单词数
- Json,List,Map的数据格式详解。
- 控制并发线程数的Semaphore和线程之间的数据交换Exchanger
- 给定一个字符串,问是否能够通过添加一个字母将其变成“回文串”
- int转换成NSData
- centos7 yum安装配置redis 并设置密码
- Git远程连接Github常见问题
- 卸载wdcp面板命令