You are given an array of k
linked-lists lists
, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.
Merge k Sorted Lists - LeetCode
💥💥💥쉬울 줄 알았는데 ㅋㅋ.. Heap 을 생각하는 것 까진 쉬었으나, 본인이 Merge 구현을 매우 못함을 알게 되었다. 💥💥💥
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int k = lists.length;
Queue<Integer> pq = new PriorityQueue<>();
for(ListNode start : lists){
if(start == null) continue;
System.out.println("START "+start);
// 연결리스트의 맨 첫 번째 원소를 pq에 넣는다.
System.out.println("NEXT "+start.next);
System.out.println("VAL "+start.val);
pq.add(start.val);
ListNode next = start.next;
System.out.println("TEST");
// 각 연결리스트를 순회하며 PQ에 원소를 넣는다 .
while(next != null){
System.out.println(next.val);
pq.add(next.val);
next = next.next;
}
}
int size = pq.size();
System.out.println("PQ SIZE "+size);
ListNode prev = null;
ListNode first = null;
// PQ에서 원소를 하나씩 꺼내서 새로운 연결리스트를 생성한다.
if(size>0) {
first = new ListNode(pq.poll());
prev =first;
for(int j=1;j<size;j++){
int curInt = pq.poll();
ListNode cur = new ListNode(curInt);
prev.next = cur;
prev = cur;
}
}
return first;
}
}
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int k = lists.length;
Queue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>(){
@Override
public int compare(ListNode o1, ListNode o2){
return o1.val-o2.val;
}
});
for(ListNode start : lists){
if(start == null) continue;
System.out.println("START "+start);
// 연결리스트의 맨 첫 번째 원소를 pq에 넣는다.
System.out.println("NEXT "+start.next);
System.out.println("VAL "+start.val);
pq.add(start);
ListNode next = start.next;
System.out.println("TEST");
// 각 연결리스트를 순회하며 PQ에 원소를 넣는다 .
while(next != null){
System.out.println(next.val);
pq.add(next);
next = next.next;
}
}
int size = pq.size();
System.out.println("PQ SIZE "+size);
ListNode prev = null;
ListNode first = null;
if(pq.isEmpty()==false){
first = pq.poll();
first.next = null; //기존 값이 있기 때문.
prev = first;
// PQ에서 원소를 하나씩 꺼내서 새로운 연결리스트를 생성한다.
while(pq.isEmpty()==false){
ListNode cur = pq.poll();
cur.next = null; // 기존 값이 있기 때문.
prev.next = cur;
prev = cur;
}
}
return first;
}
}
처음엔, lists에 있는 리스트들을, 앞에서부터 두 개 씩 묶어가며 Merge한다. --> 시간이 엄청 걸렸다.
다른 사람 풀이중, merge하는 것을 2개 2개 2개 2개.. 그 후에는 4개 4개 4개.. 그리고 이것이 lists.length일 때 까지만 늘려가며 merge하는 방식을 사용함
if(n1!=null)
ans.next = n1;
이런식으로 구현할 수 있다는 걸 생각하지 못했었다.
ListNode temp = n1;
ListNode ans = new ListNode();
// n1 list에 연결된 노드들을 순회하며,"하나씩" ans list에 연결하고자 할 때
while(temp != null){
ans.next = temp;
temp = temp.next;
ans = ans.next;
}
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int k = lists.length;
if(k==0)return null;
if(k==1) return lists[0];
int interval = 1;
while (interval < lists.length) {
for (int i = 0; i + interval < lists.length; i = i + interval * 2) {
lists[i] = mergeList(lists[i], lists[i + interval]);
}
interval *= 2;
}
return lists[0];
}
public ListNode mergeList(ListNode n1,ListNode n2){
// 비어있는 것일 경우 : [] 이러면 참 좋은데, 예시 중에 [[],[1,2]] 이런 것도 있기 때문에 고려해야한다.
// 저기서 [[]]는 결국 null인 ListNode에 해당하기 때문이다.
if(n1==null)return n2;
else if(n2==null)return n1;
ListNode ans =new ListNode();
ListNode answer = ans;
while(n1!=null && n2!=null){
// INCREMENTING implement를 해야 함.
if(n1.val>n2.val){
ans.next = n2;
ans = ans.next;
n2 = n2.next;
}else{
ans.next = n1;
ans = ans.next;
n1 = n1.next;
}
}
// 어차피 n1이라하면, 남아있는 Linked List 전체를 갖고 있는 것이라, n1만연결하면됨.
if(n1!=null){
ans.next = n1;
}
if(n2 !=null){
ans.next = n2;
}
return answer.next;
}
}
ListNode l1 = lists[0];
ListNode l2 = null;
// lists에 있는 리스트들을, 앞에서부터 두 개 씩 묶어가며 Merge한다.
for(int i=1;i<k;i++){
l2 = lists[i];
ListNode result = mergeList(l1,l2);
l1 = result;
}
return l1;
int interval = 1;
while (interval < lists.length) {
for (int i = 0; i + interval < lists.length; i = i + interval * 2) {
lists[i] = mergeList(lists[i], lists[i + interval]);
}
interval *= 2;
}
import java.util.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int k = lists.length;
if(k==0)return null;
if(k==1) return lists[0];
int interval = 1;
while (interval < lists.length) {
for (int i = 0; i + interval < lists.length; i = i + interval * 2) {
lists[i] = mergeList(lists[i], lists[i + interval]);
}
interval *= 2;
}
return lists[0];
}
public ListNode mergeList(ListNode n1,ListNode n2){
// 비어있는 것일 경우 : [] 이러면 참 좋은데, 예시 중에 [[],[1,2]] 이런 것도 있기 때문에 고려해야한다.
// 저기서 [[]]는 결국 null인 ListNode에 해당하기 때문이다.
if(n1==null)return n2;
else if(n2==null)return n1;
ListNode ans =new ListNode();
ListNode answer = ans;
while(n1!=null && n2!=null){
// INCREMENTING implement를 해야 함.
if(n1.val>n2.val){
ans.next = n2;
ans = ans.next;
n2 = n2.next;
}else{
ans.next = n1;
ans = ans.next;
n1 = n1.next;
}
}
if(n1!=null){
ans.next = n1;
}
if(n2 !=null){
ans.next = n2;
}
return answer.next;
}
}