题目:
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
Example:
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5
解答:
题目要求将小于值x的结点放到所有大于等于值x的结点的前面,且不要改变结点之间的顺序。不改变结点间的顺序为重点
解法一:
想到的思路为,遍历链表,找到第一个大于等于 x 值的结点 insnode,则将这个结点之后所有小于值x的结点,依次都移至这个 insnode 结点之前,这样就保证了不改变接结点之间的顺序
具体思路如下:
- 设置虚拟头结点 prehead,通过节点 node 遍历链表,insnode 标记需要需要插入的结点位置。
- 通过
if(node.next.val >= x && insnode==null)
判断找到链表中第一个大于等于 x 值的结点位置,insnode 为该节点的前一结点(即在此结点之后插入其他小于 x 值的结点) - 继续遍历,若找到小于 x 值的结点 node.next,将该结点记为 temp,令 node 指向 temp 的下一节点,提取该节点 temp 指向 insnode 的下一结点,将 insnode 指向该 temp 结点,完成结点的插入。并后移insnode,改变下一次插入结点的位置
- 最终返回 prenode.next
代码实现如下:
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode prehead = new ListNode(0);
prehead.next = head;
ListNode node = prehead;
ListNode insnode = null;
while(node.next != null) {
if(node.next.val >= x && insnode==null) {
insnode = node;
}
if(node.next.val < x && insnode !=null) {
ListNode temp = node.next;
node.next = node.next.next;
temp.next = insnode.next;
insnode.next = temp;
insnode = insnode.next;
continue;
}
node = node.next;
}
return prehead.next;
}
}
解法二:
看到了他人的另一种解法,比较通俗易懂,即创建两个链表,通过遍历可以分别得到大于等于x的链表和小于x的链表,然后把两个链表组合起来,就是最终所需结果
代码实现如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode list1 = new ListNode(0);
ListNode list2 = new ListNode(0);
ListNode p1 = list1;
ListNode p2 = list2;
ListNode node = head;
while(node != null) {
if(node.val < x) {
p1.next = node;
p1 = p1.next;
} else {
p2.next = node;
p2 = p2.next;
}
node = node.next;
}
p2.next = null;
p1.next = list2.next;
return list1.next;
}
}
显然,解法一更优化一些