86. Partition List
题目描述和难度
- 题目描述:给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。
- 题目难度:中等。
- 英文网址:86. Partition List 。
- 中文网址:86. 分隔链表 。
思路分析
求解关键: 其实就是我们在数组中的 partition 这个过程,在数组中,我们要通过不断地交换元素的位置来实现 partition 。对于这道问题,穿针引线可能有些麻烦,但是我们完全可以新建两个链表,最后把它们合并在一起,这是思路1;但是我们也完全可以穿针引线,只不过要设置两个头结点,最后把它们合在一起就可以了,省去了一直 new 节点的操作,这是思路2。
参考解答
参考解答1
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
public ListNode(int[] nums) {
if (nums == null || nums.length == 0) {
throw new IllegalArgumentException("arr can not be empty");
}
this.val = nums[0];
ListNode curr = this;
for (int i = 1; i < nums.length; i++) {
curr.next = new ListNode(nums[i]);
curr = curr.next;
}
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
ListNode cur = this;
while (cur != null) {
s.append(cur.val + " -> ");
cur = cur.next;
}
s.append("NULL");
return s.toString();
}
}
public class Solution {
public ListNode partition(ListNode head, int x) {
ListNode dummyNodeL = new ListNode(-1); // 比 x 小的虚拟头结点
ListNode dummyNodeR = new ListNode(-1); // 大于等于 x 的虚拟头结点
ListNode curL = dummyNodeL; // 用于遍历
ListNode curR = dummyNodeR; // 用于遍历
int val;
while (head != null) {
val = head.val;
if (val < x) { // 接在 L 的后面
curL.next = new ListNode(val);
curL = curL.next;
} else { // 接在 R 的后面
curR.next = new ListNode(val);
curR = curR.next;
}
head = head.next;
}
curL.next = dummyNodeR.next; // 把较小的链表接在较大的链表后面
return dummyNodeL.next;
}
public static void main(String[] args) {
int[] nums = {1, 4, 3, 2, 5, 2};
int x = 3;
ListNode head = new ListNode(nums);
Solution solution = new Solution();
System.out.println("分隔链表之后:");
ListNode partition = solution.partition(head, x);
System.out.println(partition);
}
}
参考解答2(推荐)
public class Solution2 {
public ListNode partition(ListNode head, int x) {
ListNode dummyNodeL = new ListNode(-1); // 比 x 小的虚拟头结点
ListNode dummyNodeR = new ListNode(-1); // 大于等于 x 的虚拟头结点
ListNode curL = dummyNodeL; // 用于遍历
ListNode curR = dummyNodeR; // 用于遍历
int val;
while (head != null) {
val = head.val;
if (val < x) {
curL.next = head;
curL = curL.next;
} else {
curR.next = head;
curR = curR.next;
}
head = head.next;
}
curL.next = dummyNodeR.next;
// 特别注意:最后这一步不能忘记,否则会产生一个循环链表
curR.next = null;
return dummyNodeL.next;
}
}