题目:
Sort a linked list in O(n log n) time using constant space complexity.
题意:对一个单链表进行排序操作,要求时间复杂度为 O(n log n),看到这里很明显想到的是归并排序,直接上代码:
1 public class Solution { 2 /* 3 类似于数组的归并操作,我们要找到中间位置一样,在单链表的归并操作中,我们同样 4 要找到中间节点,下面函数的作用就是找到单链表的中间节点, 5 在函数里面我利用快慢指针来进行。 6 */ 7 public ListNode getMidNode(ListNode list) 8 { 9 if(list == null) 10 { 11 return null; 12 } 13 ListNode slow = list; 14 ListNode fast = list; 15 while(fast.next != null && fast.next.next != null) 16 { 17 slow = slow.next; 18 fast = fast.next.next; 19 } 20 return slow; 21 } 22 /* 23 该函数的作用就是链表之间的归并操作,类似于数组之间的归并操作。 24 */ 25 public ListNode mergeList(ListNode p1,ListNode p2) 26 { 27 if(p1 == null) 28 { 29 return p2; 30 } 31 if(p2 == null) 32 { 33 return p1; 34 } 35 36 ListNode p_1 = p1; 37 ListNode p_2 = p2; 38 ListNode pTemp = null; 39 ListNode pHead = new ListNode(0); 40 if(p_1.val >= p_2.val) 41 { 42 pTemp = p_2; 43 p_2 = p_2.next; 44 }else 45 { 46 pTemp = p_1; 47 p_1 = p_1.next; 48 } 49 pHead.next = pTemp; 50 while(p_1 != null && p_2 != null) 51 { 52 if(p_1.val >= p_2.val) 53 { 54 pTemp.next = p_2; 55 pTemp = p_2; 56 p_2 = p_2.next; 57 }else 58 { 59 pTemp.next = p_1; 60 pTemp = p_1; 61 p_1 = p_1.next; 62 } 63 } 64 if(p_1 != null) 65 { 66 pTemp.next = p_1; 67 } 68 if(p_2 != null) 69 { 70 pTemp.next = p_2; 71 } 72 73 return pHead.next; 74 75 } 76 /* 77 利用递归的方法来进行归并排序。 78 */ 79 public ListNode sortList(ListNode head) { 80 if(head == null || head.next == null)//递归结束条件 81 { 82 return head; 83 } 84 85 ListNode mid = getMidNode(head);//取得中间节点 86 ListNode pBegin = head;//中间节点左边的(包括中间节点在内) 87 ListNode pEnd = mid.next;//中间节点右边的。 88 mid.next = null;//这个必须设置,因为我们进行的是两个链表的归并排序 89 pBegin = sortList(pBegin);//递归 90 pEnd = sortList(pEnd);//递归 91 return mergeList(pBegin,pEnd);//两个链表之间的合并操作 92 } 93 }
这道题解决起来并不难,在其中的难点就是递归和找中间节点,我这里利用的是快慢指针的方法,当然你也可能有其他的方法,欢迎指正!!!