[英]How to improve my code of Merge two sorted link list in Java
我通過電子郵件收到了Microsoft的一次面試問題,這很簡單,只需合並兩個排序的鏈表,並確保沒有相同的數據。
我用Java實現了它:
https://gist.github.com/cb4cd94f74cff1d2bd03
起初,我想使用遞歸,但是當列表太大時,我認為效率不高。 所以我用,而代替。
但是當我發回它時,再也沒有響應了,所以我想知道我的代碼中有什么錯誤嗎? 我應該如何改善呢?
謝謝 !
您正在檢查列表之一是否為null
然后拋出RuntimeException
嗎? 我認為,如果其中一個列表為null
,而另一個列表不是,則可以只返回第二個。 我想念什么嗎? 無論如何,如果輸入不符合您的預期,則沒有理由拋出RuntimeException
,則InvalidArgumentException
更合適。
if (head1 == null || head2 == null) {
throw new RuntimeException(
"Unavaliable source data sets, please make sure both of the two lists are not null");
}
而且,您的代碼不是最佳的。 我會講一些更簡潔的方法:(請注意使用訪問器方法,而不是直接訪問Node
類成員-由於破壞了封裝,它被認為是不好的)
Node MergeLists(Node list1, Node list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
if (list1.getData() < list2.getData()) {
list1.setNext(MergeLists(list1.getNext(), list2));
return list1;
} else {
if (list1.getData() != list2.getData()) {
list2.setNext(mergeLists(list2.getNext(), list1));
return list2;
}
Node tail = mergeLists(list2.getNext(), list1.getNext());
tail = (tail == null) ? null : tail.getNext();
list2.setNext(tail);
return list2;
}
}
您可以改善算法以解決如下列表:
1 -> 4 -> 6 -> 8 -> 12
2 -> 3 -> 9 -> 10 -> 19
與您的算法:
1: 1 -> 2 -> 4 -> 6 -> 8 -> 12 Node1: 1, Node2: 2
2: 1 -> 2 -> 3 -> 4 -> 6 -> 8 -> 12 Node1: 2, Node2: 3
3: 1 -> 2 -> 3 -> 4 -> 6 -> 8 -> 12 Node1: 3, Node2: 9
...
使用優化的算法,您會看到2-> 3會適合1-> 4,並且將1指向2並將3指向4。這組指令使得它:
...
tmp = head2.next;
head2.next = head1.next;
head1.next = head2;
head2 = tmp;
head1 = head1.next;
...
請參見設置head1.next = head2
然后兩行設置head1.next = head2
head1 = head1.next
。
而且,很難理解並試圖確定節點之間正在發生什么。 您的評論沒有用。 也許類似//swap the nodes
。
您的while循環可以使用退出條件。 多個出口點不是很好的樣式。 無限循環是一個很大的問題,它們使理解/繪制代碼變得更加困難。
希望這可以幫助。
編輯:這是我想出的。
public static Node merge(Node node1, Node node2){
//store head to be returned (the smallest)
Node masterHead = node1.value > node2.value? node2 : node1;
//put smaller elements at the beginning
while(node1 != null && node2.next != null && node1.value > node2.value)
{
Node nextInList2 = node2.next;
node2.next = node1;
node1 = node2;
node2 = nextInList2;
}
//merging loop
while(node1.next != null && node2 != null){
if(node1.next.value > node2.value)
{
//insert node(s) into the array
Node higherNode = node1.next;
node1.next = node2;
//advance until every node being inserted is less that the next
while(node2.next != null && higherNode.value > node2.next.value){
node2 = node2.next;
}
//point back into the list
Node nextInList2 = node2.next;
node2.next = higherNode;
node2= nextInList2;
}
node1 = node1.next;
}
if(node1.next == null)
node1.next = node2;
return masterHead;
}
我沒有測試空參數,只是因為它被假定為/我沒有把它變成微軟。
這是一個解決方案
Public static void merge(Node first, Node second){
if(first==null) return second;
if(second==null) return first;
if(first.data<second.data){
first.next = merge(first.next, second);
return first;
}else{
second.next = merge(second.next, first);
return second;
}
}
該問題由Stefan Haustein在另一個線程中解決了!
public static Node merge(Node list1, Node list2) {
if (list1 == null)
return list2;
if (list2 == null)
return list1;
Node head;
if (list1.data < list2.data) {
head = list1;
} else {
head = list2;
list2 = list1;
list1 = head;
}
while (list1.next != null && list2 != null) {
if (list1.next.data <= list2.data) {
list1 = list1.next;
} else {
Node tmp = list1.next;
list1.next = list2;
list2 = tmp;
}
}
if (list1.next == null)
list1.next = list2;
return head;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.