给定一个链表,再给定一个整数 pivot,请将链表调整为左部分都是值小于 pivot 的节点,中间部分都是值等于 pivot 的节点, 右边部分都是大于 pivot 的节点。
除此之外,对调整后的节点顺序没有更多要求。
第一行两个整数 n 和 pivot,n 表示链表的长度。
第二行 n 个整数 ai 表示链表的节点。
请在给定的函数内返回链表的头指针。
5 3 9 0 4 5 1
1 0 4 5 9
list_node * list_partition(list_node * head, int pivot)
{
//////在下面完成代码
list_node *smallHead = NULL, *smallTail = NULL;
list_node *equalHead = NULL, *equalTail = NULL;
list_node *bigHead = NULL, *bigTail = NULL;
while (head) {
if (head->val < pivot) {
if (smallHead == NULL) {
smallHead = head;
smallTail = head;
} else {
smallTail->next = head;
smallTail = head;
}
} else if (head->val == pivot) {
if (equalHead == NULL) {
equalHead = head;
equalTail = head;
} else {
equalTail->next = head;
equalTail = head;
}
} else {
if (bigHead == NULL) {
bigHead = head;
bigTail = head;
} else {
bigTail->next = head;
bigTail = head;
}
}
head = head->next;
}
if (smallTail) smallTail->next = NULL;
if (equalTail) equalTail->next = NULL;
if (bigTail) bigTail->next = NULL;
list_node *res;
if (smallHead == NULL && equalHead == NULL && bigHead == NULL) res = NULL;
else if (smallHead == NULL && equalHead == NULL) res = bigHead;
else if (smallHead == NULL && bigHead == NULL) res = equalHead;
else if (equalHead == NULL && bigHead == NULL) res = smallHead;
else if (smallHead == NULL) {
equalTail->next = bigHead;
res = equalHead;
} else if (equalTail == NULL) {
smallTail->next = bigHead;
res = smallHead;
} else if (bigTail == NULL) {
smallTail->next = equalHead;
res = smallHead;
} else {
smallTail->next = equalHead;
equalTail->next = bigHead;
res = smallHead;
}
head = res;
while (head) {
printf("%d ", head->val);
head = head->next;
}
return res; # Definition for singly-linked list. class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def partition(self, head, pivot): sh, st = None, None # 小于部分头尾 eh, et = None, None # 等于部分头尾 bh, bt = None, None # 大于部分头尾 while head: sign = head head = head.next # 保留下一节点 sign.next = None # 剥离出当前节点 不然可能会出现循环链表 if sign.val < pivot: if not sh: sh = sign st = sign else: st.next = sign st = sign elif sign.val == pivot: if not eh: eh = sign et = sign else: et.next = sign et = sign else: if not bh: bh = sign bt = sign else: bt.next = sign bt = sign if st: # 有小于部分 head = sh if eh: # 且有等于部分 st.next = eh if bh: et.next = bh elif bh: # 且无等于部分但有大于部分 st.next = bh elif et: # 无小于部分但有等于部分 head = head if head else eh if bh: et.next = bh return head if head else bh # 无小于部分也无等于部分
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
this.next = null;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().trim().split(" ");
int n = Integer.parseInt(params[0]);
int pivot = Integer.parseInt(params[1]);
String[] strList = br.readLine().trim().split(" ");
ListNode head = new ListNode(Integer.parseInt(strList[0]));
ListNode cur = head;
for(int i = 1; i < n; i++){
cur.next = new ListNode(Integer.parseInt(strList[i]));
cur = cur.next;
}
head = partition(head, pivot);
while(head != null){
System.out.print(head.val + " ");
head = head.next;
}
}
private static ListNode partition(ListNode node, int target) {
ListNode less = new ListNode(-1);
ListNode equal = new ListNode(-1);
ListNode great = new ListNode(-1);
ListNode head1 = less;
ListNode head2 = equal;
ListNode head3 = great;
while(node != null){
if(node.val < target){
less.next = new ListNode(node.val);
less = less.next;
}else if(node.val > target){
great.next = new ListNode(node.val);
great = great.next;
}else{
equal.next = new ListNode(node.val);
equal = equal.next;
}
node = node.next;
}
if(head3.next != null){
equal.next = head3.next;
head3.next = null; // 把大于链表头部的哑节点断开
}
if(head2.next != null){
less.next = head2.next;
head2.next = null; // 把等于链表头部的哑节点断开
}
return head1.next;
}
} import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int pivot = in.nextInt();
Node head = new Node(in.nextInt());
Node cur = head;
for (int i = 1; i < n; i++) {
cur.next = new Node(in.nextInt());
cur = cur.next;
}
head = listPartition(head, pivot);
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
}
public static Node listPartition(Node head, int pivot) {
Node sH = null;
Node sT = null;
Node eH = null;
Node eT = null;
Node mH = null;
Node mT = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = null;
if (head.val < pivot) {
if (sH == null) {
sH = head;
sT = head;
} else {
sT.next = head;
sT = head;
}
} else if (head.val == pivot) {
if (eH == null) {
eH = head;
eT = head;
} else {
eT.next = head;
eT = head;
}
} else {
if (mT == null) {
mH = head;
mT = head;
} else {
mT.next = head;
mT = head;
}
}
head = next;
}
if (sT != null) {
sT.next = eH;
eT = eT == null ? sT : eT;
}
if (eT != null) {
eT.next = mH;
}
return sH != null ? sH : (eH != null ? eH : mH);
}
}
class Node {
int val;
Node next;
Node(int val) {
this.val = val;
this.next = null;
}
} 5 3 9 0 4 5 1答案是 1 0 4 5 9
# include <bits/stdc++.h>
using namespace std;
struct list_node{
int val;
struct list_node * next;
};
#define Node list_node
int pivot;
list_node * input_list(void)
{
int n, val;
list_node * phead = new list_node();
list_node * cur_pnode = phead;
scanf("%d%d", &n, &pivot);
for (int i = 1; i <= n; ++i) {
scanf("%d", &val);
if (i == 1) {
cur_pnode->val = val;
cur_pnode->next = NULL;
}
else {
list_node * new_pnode = new list_node();
new_pnode->val = val;
new_pnode->next = NULL;
cur_pnode->next = new_pnode;
cur_pnode = new_pnode;
}
}
return phead;
}
void insertHead(Node *head, Node* x) {
if(x==NULL || head==NULL) return;
Node* last = head->next;
head->next = x;
x ->next = last;
}
list_node * list_partition(list_node * head, int pivot)
{
//////在下面完成代码
if(head==NULL || head->next ==NULL)return head;
Node dummy_head;
list_node *first = head;
list_node lt,gt,eq;
Node *l = <,*g = >, *e = &eq;
lt.next = gt.next = eq.next = NULL;
while(first) {
if(first ->val == pivot) {
e ->next = first,first = first->next,e = e->next,e->next = NULL;
}else if(first->val > pivot) {
g ->next = first,first = first->next, g = g->next,g->next = NULL;
}else {
l->next = first,l = l->next,first = first->next, l->next = NULL;
}
}
e->next = gt.next;
l->next = eq.next;
first = lt.next;
while(first) {
printf("%d ", first->val);
first = first->next;
}
return lt.next;
}
int main ()
{
list_node * head = input_list();
list_partition(head, pivot);
return 0;
}
list_node * list_partition(list_node * head, int pivot)
{
//原理:建立一个新链表,根据比较值,把原链表一个个插入,具体分成三段。
//小于在前,等于在中,大于在后。并且找到每段的头结点,小于时,第一段头结点在新链表头。
//等于时,第二段表头在第一段的链尾。大于时,第三段表头在第二段链尾。再对每段进行头插法
//mid和t用于记录第一段链尾和第二段链尾(也是第二段和第三段的表头)
//p用于遍历旧链表。h,mid,t分别标记新链表三段的表头。lr用于临时指针,标记p的位置方便插入。
//f1和f2用于下面所说的标记先后顺序和互斥的关系
//由于都是采用头插法。
//小于时,第一次插入的节点就是第一段的链尾,第二段的表头和还可能是第三段的表头;
//等于时,第一次插入的节点就是第二段的链尾,第三段的表头。
//其中,小于和等于的情况稍微复杂一点,因为小于和等于都会影响第三段表头的位置。这与它们的执行顺序有关。
//如果小于的情况先于等于的情况插入,那么在小于的情况中,标记第二段表头mid时,还要标记第三段的表头。
//如果等于的情况先于小于的情况插入,那么在小于的情况中,标记第二段表头mid时,不用标记第三段表头。
//例如:k=3,先后插入2、9,5。2不光是第二段表头还是第三段表头。结果2-5-9。
//例如:k=3,先后插入2、9、3、4、3、5第三段的表头先被设置为2,随后被设置3(第三个)。结果2-3(5)-3(3)-5-4-9
list_node *new_head = new list_node();
new_head->next = NULL;
list_node *h,*mid,*t,*p,*lr;
h = mid = t = new_head;
p = head;
int f1 = 1,f2 = 1;
while(p != NULL){
if(p->val > pivot){
lr= p;
p = p->next;
lr->next = t->next;
t->next = lr;
}
else if(p->val < pivot){
if(f1 == 1 && f2 == 1){
mid = p;
t = p;
f2 ++;
}
if(f1 == 2 && f2 == 1) {
mid = p;
f2++;
}
lr = p;
p = p->next;
lr->next = h->next;
h->next = lr;
}
else{
if(f1 == 1){
t = p;
f1++;
}
lr = p;
p = p->next;
lr->next = mid->next;
mid->next =lr;
}
}
return new_head->next;
} 思路(左神版):
1.将链表存到数组中
2.利用快排的partion函数调整数组
3.将数组重新连成链表
import java.io.*;
public class Main {
static int n, k;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] str = br.readLine().split(" ");
n = Integer.parseInt(str[0]);
k = Integer.parseInt(str[1]);
Node h = new Node(-1);
Node p = h;
String[] s1 = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
p.next = new Node(Integer.parseInt(s1[i]));
p = p.next;
}
h = h.next;//真实头结点
h = listPartion(h, k);
while (h != null) {
bw.write(h.val + " ");
h = h.next;
}
bw.newLine();
bw.flush();
}
private static Node listPartion(Node h, int k) {
Node cur = h;
Node[] arr = new Node[n];
int i = 0;
//将链表存到数组
for (i = 0; i != n; i++) {
arr[i] = cur;
cur = cur.next;
}
//调整数组
arrPartion(arr, k);
//重新连成链表
for (i = 1; i != n; i++) {
arr[i - 1].next = arr[i];
}
arr[i - 1].next = null;
return arr[0];
}
private static void arrPartion(Node[] arr, int k) {
int small = -1, big = arr.length;
int index = 0;
while (index != big) {
if (arr[index].val < k) {
swap(arr, ++small, index++);
} else if (arr[index].val == k) {
index++;
} else {
swap(arr, --big, index);
}
}
}
private static void swap(Node[] arr, int i, int j) {
Node tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static class Node {
public int value;
public Node next;
public Node(int value) {
this.value = value;
}
}
public static Node listGenerator(int length, String[] numbers) {
Node head = new Node(Integer.parseInt(numbers[0]));
Node cur = head;
for (int i = 1; i < length; i++) {
cur.next = new Node(Integer.parseInt(numbers[i]));
cur = cur.next;
}
cur.next = null;
return head;
}
public static void printList(Node head) {
while (head != null) {
System.out.print(head.value +" ");
head = head.next;
}
System.out.println();
}
public static Node listPartition(Node head, int pivot) {
Node lessHead = null;
Node lessTail = null;
Node equalHead = null;
Node equalTail = null;
Node moreHead = null;
Node moreTail = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = null;
if(head.value < pivot) {
if (lessHead == null) {
lessHead = head;
lessTail = lessHead;
} else {
lessTail.next = head;
lessTail = lessTail.next;
}
} else if (head.value == pivot) {
if (equalHead == null) {
equalHead = head;
equalTail = equalHead;
} else {
equalTail.next = head;
equalTail = equalTail.next;
}
} else {
if (moreHead == null) {
moreHead = head;
moreTail = moreHead;
} else {
moreTail.next = head;
moreTail = moreTail.next;
}
}
head = next;
}
if (lessHead != null) {
lessTail.next = equalHead;
equalTail = equalTail == null ? lessTail : equalTail;
}
if (equalTail != null) {
equalTail.next = moreHead;
}
return lessHead != null ? lessHead : equalHead != null ? equalHead : moreHead;
}
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] parameters = bufferedReader.readLine().split(" ");
int n = Integer.parseInt(parameters[0]);
int pivot = Integer.parseInt(parameters[1]);
String[] numbers = bufferedReader.readLine().split(" ");
Node head = listGenerator(n, numbers);
head = listPartition(head, pivot);
printList(head);
}
} import java.util.Scanner;
/**
*
* @author minghai
* @date 2019年9月6日
*/
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int pivot = scan.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = scan.nextInt();
}
arrPartition(arr,pivot);
for(int a:arr){
System.out.print(a+" ");
}
}
private static void arrPartition(int[] nodeArr, int pivot) {
int small = -1;
int big = nodeArr.length;
int index = 0;
while(index != big) {
if(nodeArr[index] < pivot) {
swap(nodeArr,++small,index++);
}else if(nodeArr[index] == pivot) {
index++;
}else {
swap(nodeArr, --big, index);
}
}
}
private static void swap(int[] nodeArr, int i, int j) {
int temp = nodeArr[i];
nodeArr[i] = nodeArr[j];
nodeArr[j] = temp;
}
} 方法2:还是超时,不过思路很好,可以实现数据的稳定性,代码为 左神《程序员代码面试指南》中此题金阶题的代码,不过在此OJ测试中,超时,可以通过在从控制台输入时,每取到一个值就判断该值与目标值的大小或相等,然后加到对应的 大、中、小链表中,可以减少一次时间一次循环时间。 package ch02_linked;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int pivot = scan.nextInt();
Node head = new Node(scan.nextInt());
Node cur = head;
while(--n > 0) {
cur.next = new Node(scan.nextInt());
cur = cur.next;
}
cur = listPartition2(head, pivot);
while(cur!=null) {
System.out.print(cur.val+" ");
cur = cur.next;
}
}
public static Node listPartition2(Node head, int pivot) {
Node sH = null;
Node sT = null;
Node eH = null;
Node eT = null;
Node bH = null;
Node bT = null;
Node next = null;
while(head != null) {
next = head.next;
head.next = null;
if(head.val < pivot) {
if(sH == null) {
sH = head;
sT = head;
}else {
sT.next = head;
sT = sT.next;
}
}else if(head.val == pivot) {
if(eH == null) {
eH = head;
eT = head;
}else {
eT.next = head;
eT = eT.next;
}
}else {
if(bH == null) {
bH = head;
bT = head;
}else {
bT.next = head;
bT = bT.next;
}
}
head = next;
}
if(sT != null) {
sT.next = eH;
eT = eT == null ? sT : eT;
}
if(eT != null) {
eT.next = bH;
}
return sH != null ? sH : eH != null ? eH : bH;
}
}