将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的,且合并后新链表依然有序。
数据范围:链表长度
,链表中的值
要求:空间复杂度
,时间复杂度
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val > l2.val) {
l2.next = mergeTwoLists(l1,l2.next);
return l2;
}else{
l1.next = mergeTwoLists(l1.next,l2);
return l1;
}
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
ListNode head = new ListNode(-1), p = head;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
p.next = l1;
l1 = l1.next;
}else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if(l1 != null){
p.next = l1;
}else {
p.next = l2;
}
return head.next;
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
if(l1 == null && l2 == null){
return null;
}else{
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
}
ListNode head = l1;
ListNode temp = l2;
if(l1.val <= l2.val){
head = l1;
temp = l2;
}else{
head= l2;
temp = l1;
}
ListNode cur = head.next;
ListNode resHead = head;
resHead.next = null;
while(cur!=null && temp!=null){
while(cur!=null && temp != null && cur.val <= temp.val){
resHead.next = cur;
resHead = resHead.next;
cur = cur.next;
}
while(cur!=null && temp != null && cur.val > temp.val){
resHead.next = temp;
resHead = resHead.next;
temp = temp.next;
}
}
while(cur != null){
resHead.next = cur;
resHead = resHead.next;
cur =cur.next;
}
while(temp != null){
resHead.next = temp;
resHead = resHead.next;
temp =temp.next;
}
return head;
}
} public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
ListNode head = new ListNode(0);
ListNode s = head;
while(l1 != null && l2 != null){
if(l1.val<l2.val){
s.next = l1;
s = l1;
l1 = l1.next;
}
else{
s.next = l2;
s = l2;
l2 = l2.next;
}
}
if(l1!=null)
s.next = l1;
if(l2!=null)
s.next = l2;
return head.next;
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
if(l1==null){
return l2;
}
if(l2==null){
return l1;
}
ListNode head = l1.val<l2.val?l1:l2;
ListNode cur = head;
ListNode other = l1.val<l2.val?l2:l1;
while(cur.next!=null&&other!=null){
if(cur.next.val<=other.val){
cur=cur.next;
}else{
ListNode tmp = cur.next;
cur.next = other;
cur = other;
other = tmp;
}
}
if(cur.next==null&&other!=null){
cur.next=other;
}
return head;
}
} /*
二刷
思路:
1.输入问题:考虑为空!
2.新链表的第一个结点问题,由于一般情况下第一个结点都需要特殊处理,比较实用的解决办法是在第一个结点前增加一个虚拟的头结点(例如下面的head),
讲实际的第一个结点一般化。最后输出的时候输出这个虚拟结点的下一个结点就OK
3.如何为新链表选择下一个结点(已经虚拟出第一个结点了。)这个比较容易,比大小就OK了。取小的并并在此链表前进一步。
4.注意循环的终止条件!
5.终止后并没有结束!
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode pre=new ListNode(0);
ListNode head=pre;
while(l1!=null&&l2!=null){
if(l1.val<=l2.val){
head.next=l1;
head=head.next;
l1=l1.next;
}
else{
head.next=l2;
head=head.next;
l2=l2.next;
}
}
while(l1==null&&l2!=null){
head.next=l2;
head=head.next;
l2=l2.next;
}
while(l2==null&&l1!=null){
head.next=l1;
head=head.next;
l1=l1.next;
}
return pre.next;
}} public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//和数组法一样的解法
//合并有序链表 和合并有序数组思想是一致的
//双指针不停找到两个链表中的较小的那个 然后加入哑巴节点为头的链表
//哑巴节点方便处理边界问题
//这种合并有序题 不管是数组还是链表 都是双指针套路 因为初态有序。
//不直接操作链表 而是使用的引用
ListNode p=l1,q=l2,dumbNode=new ListNode(-1);
ListNode temp = dumbNode;//temp是用来形成结果链表的
while (p!=null&&q!=null){
if (p.val<=q.val){//如果p小 那么让temp.next指向p
temp.next = p;
p = p.next;//p后移
}else if (p.val>q.val){//如果q小 那么让temp.next指向q
temp.next=q;
q=q.next;
}
temp =temp.next;//非常关键!! temp光指定next还不够 还得去自己的next
//这样才是迭代
}
//出循环 代表 l1和l2至少有一个已经走完了 或者天然的 一个为空链表
//也就是说 还要处理剩下没被处理的的节点
//如果l1为空 那么意味着l2里剩下的节点要全部直接给temp.next
//同理如果l1不为空 那l2为空的话 把剩下的l1加到temp.next
//如果都空 那么temp.next = null
temp.next=(p==null)?q:p;
return dumbNode.next;
} public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// 特殊情况处理
if (l1 == null && l2 == null) {
return null;
}
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
// 一次归并操作
ListNode dummyNode = new ListNode(-1);
ListNode current = dummyNode;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
if (l1 != null) {
current.next = l1;
}
if (l2 != null) {
current.next = l2;
}
return dummyNode.next;
}
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
//递归的思想
if(l1==null) return l2;
if(l2==null) return l1;
ListNode node = null;
if(l1.val<l2.val){
node=l1;
node.next=mergeTwoLists(l1.next,l2);
}
else{
node=l2;
node.next=mergeTwoLists(l1,l2.next);
}
return node;
} public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
ListNode p1 = l1;
ListNode p2 = l2;
ListNode l = new ListNode(6);
l.next = null;
ListNode q = l;
while(p1!=null&&p2!=null){
if(p1.val<=p2.val){
q.next=p1;
q = q.next;
p1 = p1.next;
q.next=null;
}else if(p1.val>p2.val){
q.next=p2;
q=q.next;
p2=p2.next;
q.next=null;
}
}
while(p1!=null){
q.next=p1;
p1=p1.next;
q=q.next;
}
while(p2!=null){
q.next=p2;
p2=p2.next;
q=q.next;
}
q.next=null;
return l.next;
} 这道题说起来还蛮简单的
总体的思想就是归并排序合并的思想,包括 l1 l2 已经有序所以只需要有序比对合并即可。
注意边界条件及一些临时指针即可
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
if(l1==null&&l2==null){
return null;
}
if(l1!=null&&l2==null){
return l1;
}
if(l1==null&&l2!=null){
return l2;
}
//初始化新链表头节点 这里注意 l1 l2 为有序 类似归并排序
ListNode resultNodeHead=null;
if(l1.val<l2.val){
resultNodeHead=l1;
l1=l1.next;
}else{
resultNodeHead=l2;
l2=l2.next;
}
ListNode tmpNode=resultNodeHead;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
tmpNode.next=l1;
l1=l1.next;
}else{
tmpNode.next=l2;
l2=l2.next;
}
tmpNode=tmpNode.next;
}
while(l1!=null){
tmpNode.next=l1;
l1=l1.next;
tmpNode=tmpNode.next;
}
while(l2!=null){
tmpNode.next=l2;
l2=l2.next;
tmpNode=tmpNode.next;
}
return resultNodeHead;
}
}思考了一下 最后两个 while 没什么必要了,因为是有序链表所以直接指向就可以了
if(l1!=null){
tmpNode.next=l1;
}
if(l2!=null){
tmpNode.next=l2;
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
ListNode node = head;
while(l1 != null && l2 != null) {
if(l1.val <= l2.val) {
node.next = l1;
l1 = l1.next;
}else {
node.next = l2;
l2 = l2.next;
}
node = node.next;
}
if(l1 != null) {
node.next = l1;
}
if(l2 != null) {
node.next = l2;
}
return head.next;
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
ListNode dum = new ListNode(0),cur = dum;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 != null ? l1:l2;
return dum.next;
}
} 思路:伪造零时节点dum,比较l1和l2的大小,谁小每次就把cur.next等于谁。无论谁大谁小每次都把cur置为cur.next,也就是l1,l2中的较小者。最后是三目运算判断。import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
ListNode head = new ListNode(-1);
ListNode headTemp = head;
ListNode node1 = l1;
ListNode node2 = l2;
while(node1!=null && node2!=null){
//2个链表中含重复元素
if(node1.val <= node2.val){
head.next = node1;
head = node1;
node1 = node1.next;
}else if(node1.val > node2.val){
head.next = node2;
head = node2;
node2 = node2.next;
}
}
//链表1长度>链表2长度 链表2遍历完了
if(node1!=null){
head.next = node1;
}
//链表1长度<链表2长度 链表1遍历完了
if(node2!=null){
head.next = node2;
}
return headTemp.next;
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {//
// write code here
if(l1 == null) return l2;
if(l2 == null) return l1;
ListNode newHead = new ListNode(-1);
ListNode cur = newHead;
//考虑升序还是降序,先升序把
while(l1 != null && l2 != null){
if(l1.val < l2.val){
//l1小,先将l1插入新链表末尾
cur.next = l1;
//l1进入后,更新l1
l1 = l1.next;
} else{
cur.next = l1;
l2 = l2.next;
}
//更新cur
cur = cur.next;
}
//循环结束,l1或者l2可能为空,应该继续拼接
cur.next = l1 != null ? l1 : l2;
//最后将无意义头节点删除
return newHead.next;
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
// 思路:递归
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// 递归边界
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
// 递归
if(l1.val < l2.val){
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}else{
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
public class Solution {
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
//判断空
if(l1 == null) return l2;
if(l2 == null) return l1;
//新建节点保存
ListNode newNode = new ListNode(0);//重点,需要初始化头节点
ListNode node = newNode;
while(l1!=null && l2!=null){
if(l1.val < l2.val){
newNode.next = l1;
l1 = l1.next;
}
else{
newNode.next = l2;
l2 = l2.next;
}
newNode = newNode.next;
}
if(l1 != null)
newNode.next = l1;
else
newNode.next = l2;
return node.next; //返回头节点下一个
}
}