题目
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。示例如下:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
解决思路
- 创建两个虚拟头节点small和big,创建两个指针s和b分别指向虚拟头结点small和big,创建指针q记录head的下一个节点。
- 遍历链表,当节点的值小于给定的值时,将该节点链入到samll对应的链表中(注意对应指针要向前移动)。
- 当节点的值大于给定的值时,将该节点链入big对应的链表中(注意对应指针要向前移动)。
- 最后将small对应的链表和big对应的链表合并为一条链表。
代码
- C++代码
# include <stdio.h>
struct ListNode {
int val;
ListNode *next;
ListNode(): val(0), next(nullptr) {}
ListNode(int val): val(val), next(nullptr) {}
ListNode(ListNode *next): val(0), next(next) {}
ListNode(int val, ListNode *next): val(val), next(next) {}
};
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if (nullptr == head) {
return head;
}
ListNode small; // 虚拟头节点1
ListNode big; // 虚拟头节点2
ListNode *s = &small; // 链表分隔后,s指向small所在链表的尾结点
ListNode *b = &big; // 链表分隔后,b指向big所在链表的尾结点
ListNode *h = head;
ListNode *q; // 记录h的下一个节点
// 遍历每一个节点,判断将节点的值与给定的值的大小
while (h) {
q = h->next;
if (h->val < x) { // 节点的值小于给定的值,将该节点链入small对应的链表中
h->next = s->next; // 即h->next = nullptr
s->next = h;
s = h;
} else { // 节点的值大于给定的值,将该节点链入big对应的链表中
h->next = b->next; // 即h->next = nullptr
b->next = h;
b = h;
}
h = q;
}
s->next = big.next; // 将small和big对应的链表连接成一条链表
return small.next;
}
};
int main() {
ListNode *a = new ListNode(1);
ListNode *b = new ListNode(4);
ListNode *c = new ListNode(3);
ListNode *d = new ListNode(2);
ListNode *e = new ListNode(5);
ListNode *f = new ListNode(2);
ListNode *head = a;
a->next = b;
b->next = c;
c->next = d;
d->next = e;
e->next = f;
printf("before split: ");
while (head) {
printf("%d ", head->val);
head = head->next;
}
printf("\n");
head = a;
int k = 3;
Solution *solution = new Solution();
ListNode *ret = solution->partition(head, k);
printf("after split: ");
while (ret) {
printf("%d ", ret->val);
ret = ret->next;
}
return 0;
}
- python代码
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
if not head:
return head
small: ListNode = ListNode() # 虚拟头节点1
big: ListNode = ListNode() # 虚拟头节点2
s: ListNode = small # 链表分隔后,s指向small所在链表的尾结点
b: ListNode = big # 链表分隔后,b指向big所在链表的尾结点
h: ListNode = head
q: ListNode # 记录h的下一个节点
# 遍历每一个节点,判断将节点的值与给定的值的大小
while h:
q = h.next
if h.val < x: # 节点的值小于给定的值,将该节点链入small对应的链表中
h.next = s.next # 即h->next = None
s.next = h
s = h
else: # 节点的值大于给定的值,将该节点链入big对应的链表中
h.next = b.next # 即h->next = None;
b.next = h
b = h
h = q
s.next = big.next # 将small和big对应的链表连接成一条链表
return small.next
def main():
a: ListNode = ListNode(1)
b: ListNode = ListNode(4)
c: ListNode = ListNode(3)
d: ListNode = ListNode(2)
e: ListNode = ListNode(5)
f: ListNode = ListNode(2)
head: ListNode = a
a.next = b
b.next = c
c.next = d
d.next = e
e.next = f
print("before split: ", end='')
while head:
print(head.val, end=' ')
head = head.next
print()
head = a
k: int = 3
solution: Solution = Solution()
ret: ListNode = solution.partition(head, k)
print("after split: ", end='')
while ret:
print(ret.val, end=' ')
ret = ret.next
if __name__ == "__main__":
main()
说明
- 对应LeetCode第86题。
- 链接:https://leetcode-cn.com/problems/partition-list/