链表节点定义
public class ListNode {
public int value;
public ListNode next;
public ListNode(int value, ListNode next) {
this.value = value;
this.next = next;
}
public ListNode() {
}
public ListNode(int value) {
this.value = value;
}
}
合并链表问题
合并俩有序链表
- LeetCode21:leetcode-cn.com/problems/me…
- 剑指offer17
解法1 while循环
-
①只要有一个为空只要返回另外一个即可
-
②不必纠结第一个节点选择哪个List里的,直接新建个node作为头结点最后返回其next即可
-
③两个指针分别指向两个List.哪个小就接上
-
④如果一个=null了,剩下那个直接接上就行,不必再循环了
-
时间复杂度:O(n + m)
-
空间复杂度:O(1)
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null){
return l2;
}
if(l2==null){
return l1;
} //---------------------------------------①
ListNode p = l1, q = l2;
ListNode newHead = new ListNode(0);//------②
ListNode h = newHead;
while (p != null && q != null) {//---------③
if (p.val < q.val) {
h.next = p;
p = p.next;
h=h.next;
}else {
h.next = q;
q = q.next;
h=h.next;
}
}
if(p!=null){
h.next = p; //---------------------------④
}
if(q!=null){
h.next = q;
}
return newHead.next;
}
解法2 递归
如果node1.val>node2.val list就变成 node1->merge(node1.next,node2) 反之同样
- 时间复杂度:O(n + m) 与合并后的链表长度为线性关系。
- 空间复杂度:O(n + m)调用 mergeTwoLists 退出时 l1 和 l2 中每个元素都一定已经被遍历过了,所以 n + m个栈帧会消耗 O(n + m) 的空间。
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else 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;
}
}
其他问题
单链表反转
剑指offer16 仨指针
public static ListNode reverse(ListNode node) {
if (node == null || node.next == null) {
return node;
}
ListNode pre=null ,next= null;
ListNode cur = node;
while (cur != null) {
next=cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
edit-log 2020.03.29
review-log