题目:
给定一个单向链表的头节点 head,节点的值类型是整数,再给定一个整数 pivot。实现一个调整链表的函数,将链表调整为左边部分都是小于 pivot 的节点,中间部分值都是等于 pivot 的节点,右边都是值大于 pivot 的节点。除这个要求外,对调整后的节点顺序没有更多要求。
例如:链表 9->0->4->5->1, pivot=3
调整后链表可以是 1->0->4->9->5,也可以是 0->1->9->5->4
进阶:
在原题目的要求上再增加如下两个要求。
1. 在左、中、右三个部分的内部也做顺序要求,要求每部分里的节点从左到右的顺序与原链表中节点的先后顺序一样。
如:9->0->4->5->1,pivot=3,调整后的链表是 0->1->9->4->5,在满足原问题要求的同时,从左向右为0、1,原链表也是先0后1,后面同理。
2. 时间复杂度O(N),额外空间复杂度为O(1)。
1 public Node listPartition(Node head, int pivot) 2 { 3 if(head == null) 4 return head; 5 6 Node cur = head; 7 int i = 0; 8 while(cur != null) 9 { 10 i++; 11 cur = cur.next; 12 } 13 Node[] nodeArr = new Node[i]; 14 cur = head; 15 for(i = 0; i != nodeArr.length; i++) 16 { 17 nodeArr[i] = cur; 18 cur = cur.next; 19 } 20 arrPartition(nodeArr, pivot); 21 for(i = 1; i != nodeArr.length; i++) 22 { 23 nodeArr[i-1].next = nodeArr[i]; 24 } 25 nodeArr[i-1].next = null; 26 return nodeArr[0]; 27 } 28 29 public void arrPartition(Node[] arr, int pivot) 30 { 31 int samll = -1, big = arr.length, index = 0; 32 while(index != big) 33 { 34 if(nodeArr[index].data < pivot) 35 { 36 swap(nodeArr, ++small, index++); 37 } 38 else if(nodeArr[index].data == pivot) 39 { 40 index++; 41 } 42 else 43 { 44 swap(nodeArr, --big, index); 45 } 46 } 47 } 48 49 public void swap(Node[] nodeArr, int a, int b) 50 { 51 Node tmp = nodeArr[a]; 52 nodeArr[a] = nodeArr[b]; 53 nodeArr[b] = tmp; 54 }
进阶解法:
1. 将原链表中的所有节点依次划分为三个链表,三个链表分别为 small、equal、big,分别代表左边、中间、右边
2. 将 smal、equal和big三个链表重新串起来
1 public Node listPartition(Node head, int pivot) 2 { 3 Node sH = null, sT = null; //小的头和尾 4 Node eH = null, eT = null; //相等的头和尾 5 Node bH = null, bT = null; //大的头和尾 6 Node next = null; 7 8 while(head != null) 9 { 10 next = head.next; 11 head.next = null; 12 if(head.data < pivot) 13 { 14 if(sH != null) 15 { 16 sH = head; 17 sT = head; 18 } 19 else 20 { 21 sT.next = head; 22 sT = head; 23 } 24 } 25 else if(head.data == pivot) 26 { 27 if(eH == null) 28 { 29 eH = head; 30 eT = head; 31 } 32 else 33 { 34 eT.next = head; 35 eT = head; 36 } 37 } 38 else 39 { 40 if(bH == null) 41 { 42 bH = head; 43 bT = head; 44 } 45 else 46 { 47 bT.next = head; 48 bT = head; 49 } 50 } 51 head = next; 52 } 53 if(sT != null) 54 { 55 sT.next = eH; 56 eT = eT == null ? sT : eT; 57 } 58 if(eT != null) 59 { 60 eT.next = bH; 61 } 62 return sH != null ? sH : eH != null ? eH : bH; 63 }
参考资料:程序员代码面试指南 IT名企算法与数据结构题目最优解,左程云