21두 개의 순서 연결 리스트 병합
제목 설명
두 개의 오름차순 연결 목록을 새로운 오름차순 연결 목록으로 병합하고 돌아옵니다. 새로운 연결리스트는 주어진 두 연결리스트의 모든 노드를 연결하여 형성됩니다.
예시 1:
진입:l1 = [1,2,4], l2 = [1,3,4] 모욕:[1,1,2,3,4,4]예시 2:
욕조:l1=[], l2=[] 모욕:[]예시 3:
욕조:l1=[], l2=[0] 모욕:[0]
질문 아이디어:
1. 이중 포인터 방법:
시간 복잡도: O(M+N)
새로운 연결리스트를 정의한 후, 임시 연결리스트를 정의하고, 두 개의 연결리스트를 순회하여 list1과 list2의 값을 비교하여 작은 것을 임시 연결리스트에 넣는다. 목록은 다음 연결 목록으로 이동해야 합니다. list1과 list2 간의 다음 비교를 계속합니다.
삽화:
비유하자면 특정 연결리스트를 순회하면 순회하지 않은 나머지 연결리스트는 모두 tmp에 들어가고 마지막으로 tmp 레코드의 헤드 노드가 반환됩니다.
2. 재귀적 방법:
시간 복잡도: O(M+N)
어느 노드가 더 작은지 판단한 후 작은 연결리스트의 방향을 바꾸면 두 연결리스트가 합쳐지는 것이라고 볼 수 있는데 이게 재귀 아닌가요?
그림과 같이:
이때 순서가 지정된 두 개의 연결 목록을 병합하는 작업이 여전히 필요합니다.
등등
코드 데모
이중 포인터 방법:
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1 == null) return list2;
if(list2 == null) return list1;
ListNode listnode = new ListNode();
ListNode tmp = listnode;
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;
}
}
if(list1 != null) {
tmp.next = list1;
}
if(list2 != null) {
tmp.next = list2;
}
return listnode.next;
}
}
재귀적 방법:
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1 == null) return list2;
if(list2 == null) return list1;
if(list1.val <= list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
}
list2.next = mergeTwoLists(list2.next, list1);
return list2;
}
}