23. 合并K个升序链表
思路:
方法1:可以采用归并排序的思路,先两组两组分开,然后两两合并,自然而然要用到递归了。
首先定义递归出口:
if(lists.length == 0) return null;
if(lists.length == 1) return lists[0];
if(lists.length == 2) return mergeTwoLists(lists[0],lists[1]);
然后将数组分为两组:
int mid = lists.length/2;
ListNode[] l1 = new ListNode[mid];
for(int i=0;i<mid;i++) l1[i] = lists[i];
ListNode[] l2 = new ListNode[lists.length-mid];
for(int i=mid,j=0;i<lists.length;i++,j++) l2[j] = lists[i];
进行两两分割和合并:
return mergeTwoLists(mergeKLists(l1),mergeKLists(l2));
再来定义mergeTwoLists函数,合并两链表可以采用递归也可以采用迭代,这里就不一一解释了:
public ListNode mergeTwoLists(ListNode l1,ListNode l2){//迭代
if(l1 == null) return l2;
if(l2 == null) return l1;
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
cur.next = l1;
l1 = l1.next;
cur = cur.next;
}else{
cur.next = l2;
l2 = l2.next;
cur = cur.next;
}
}
ListNode p = null;
if(l1 != null){
p = l1;
}else if(l2 != null){
p = l2;
}else{
return dummy.next;
}
cur.next = p;
return dummy.next;
}
public ListNode mergeTwoLists(ListNode l1,ListNode l2){//递归
if(l1 == null) return l2;
if(l2 == null) return l1;
ListNode head = null;
if(l1.val < l2.val){
head = l1;
head.next = mergeTwoLists(l1.next,l2);
}else{
head = l2;
head.next = mergeTwoLists(l2.next,l1);
}
return head;
}
方法2:还有一种更加简洁的方法,我们可以采用《丑数》的思路,每次从所有链表的头节点开始,比较所有头节点的大小,取出最小的那个,然后被取链表的下一个节点再与其他链表的头节点相比较,直到所有节点比较完,因为我们每次取出最小节点,所以我们可以采用堆来存放这些节点:
public ListNode mergeKLists(ListNode[] lists){
if(lists.length == 0) return null;
if(lists.length == 1) return lists[0];
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
PriorityQueue<ListNode> queue = new PriorityQueue<>((head1,head2)->(head1.val-head2.val));
for(ListNode head : lists){
if(head == null) continue;
queue.add(head);
}
while(!queue.isEmpty()){
ListNode head = queue.poll();
cur.next = head;
cur = cur.next;
if(head.next != null) queue.add(head.next);
cur.next = null;
}
return dummy.next;
}
328. 奇偶链表
思路:
这一题挺简单的,但是当时脑袋没有转过来弯想的竟然是直接把偶数节点往队尾差,这样实在太麻烦了,应该直接将链表奇偶分开再连接到尾部即可:
public ListNode oddEvenList(ListNode head) {
if (head == null) {
return head;
}
ListNode odd = head, even = head.next, evenHead = even;
while (even != null && even.next != null) {
odd.next = odd.next.next;
odd = odd.next;
even.next = even.next.next;
even = even.next;
}
odd.next = evenHead;
return head;
}