给定一个单向链表的头节点head, 节点的值类型是整型, 再给定一个整数pivot。
实现一个调整链表的函数, 将链表调整为左部分都是值小于 pivot的节点, 中间部分都是值等于pivot的节点, 右部分都是值大于 pivot的节点。
除这个要求外, 对调整后的节点顺序没有更多的要求。 例如: 链表9->0->4->5->1, pivot=3。
调整后链表可以是1->0->4->9->5, 也可以是0->1->9->5->4。 总之, 满足左部分都是小于3的节点, 中间部分都是等于3的节点(本例中这个部
分为空) , 右部分都是大于3的节点即可。 对某部分内部的节点顺序不做 要求。
进阶: 在原问题的要求之上再增加如下两个要求。
在左、 中、 右三个部分的内部也做顺序要求, 要求每部分里的节点从左到右的顺序与原链表中节点的先后次序一致。
例如: 链表9->0->4->5->1, pivot=3。调整后的链表是0->1->9->4->5。 在满足原问题要求的同时,左部分节点从左到右为0、 1。 在原链表中也是先出现0,后出现1; 中间部分在本例中为空, 不再讨论; 右部分节点 从左到右为9、 4、 5。 在原链表中也是先出现9, 然后出现4,最后出现5。
如果链表长度为N, 时间复杂度请达到O(N), 额外空间复杂度请达到O(1)。
解法一:
准备三个栈,small,equal,big,遍历链表,将不同的大小的结点放入不同的栈中,最后连接起来即可
public static Node smallerEqualBigger(Node head, int pivot){ if(head == null || head.next == null) return head; Stack<Node> small = new Stack<>(); Stack<Node> equal = new Stack<>(); Stack<Node> big = new Stack<>(); while(head != null){ if(head.val < pivot){ small.push(head); } else if(head.val == pivot){ equal.push(head); }else{ big.push(head); } head = head.next; } Node node = new Node(0); head = node; while(!small.empty()){ node.next = small.pop(); node = node.next; } while(!equal.empty()){ node.next = equal.pop(); node = node.next; } while(!big.empty()){ node.next = big.pop(); node = node.next; } node.next = null; return head.next; }
解法二:还可以利用荷兰国旗的方法,将链表中的每个结点放到一个数组中,然后利用荷兰国旗的partition来进行划分,得到的划分结果就是结果,然后在重新串起来。
但是荷兰国旗的空间复杂度是O(N),且稳定性不好。
进阶:
1.相对次序不变
2.如果链表长度为N, 时间复杂度请达到O(N), 额外空间复杂度请达到O(1)
解法二:
准备三个头结点smallHead, equalHead, bigHead,
遍历一遍链表,将不同大小的结点挂在不同的结点上,最后将三个链表连接起来即可
public static Node smallerEqualBigger2(Node head, int pivot){ if(head == null || head.next == null) return head; Node smallHead = new Node(0); Node equalHead = new Node(0); Node bigHead = new Node(0); Node small = smallHead; Node equal = equalHead; Node big = bigHead; while(head != null){ if(head.val < pivot){ small.next = head; small = small.next; } else if(head.val == pivot){ equal.next = head; equal = equal.next; } else{ big.next = head; big = big.next; } head = head.next; } if(equalHead.next != null){ small.next = equalHead.next; } if(bigHead.next != null){ equal.next = bigHead.next; } big.next = null; return smallHead.next; }