左神算法书籍《程序员代码面试指南》——2_07将单向链表按某值划分成左边小、中间相等、右边大的形式
作者:互联网
Problem:
【题目】 给定一个单向链表的头节点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)
Solution:
使用两个指针,pr后插数来存放小数,pr前插数来存放相等的数,p为遍历游动指针
1 #pragma once 2 3 #include <iostream> 4 5 using namespace std; 6 7 8 struct Node 9 { 10 int val; 11 Node* next; 12 Node(int a = 0) :val(a), next(NULL) {} 13 }; 14 15 void Partition(Node*& head, const int num) 16 { 17 Node *pr, *p; 18 p = pr = head; 19 while (p->next) 20 { 21 if (p->next->val < num) 22 { 23 Node* q; 24 q = pr->next; 25 pr->next = p->next; 26 p->next = p->next->next; 27 pr = pr->next; 28 pr->next = q; 29 } 30 else if (p->next->val == num) 31 { 32 Node* q; 33 q = pr->next; 34 pr->next = p->next; 35 p->next = p->next->next; 36 pr->next->next = q; 37 } 38 else 39 p = p->next; 40 } 41 42 } 43 44 45 void Test() 46 { 47 int a[] = { 7,2,8,1,4,5,4,6 }; 48 Node* head = new Node(-1); 49 Node* p = head; 50 for (auto n : a) 51 { 52 Node* q = new Node(n); 53 p->next = q; 54 p = q; 55 } 56 p->next = NULL; 57 58 p = head->next; 59 cout << "原链表为: "; 60 while (p) 61 { 62 cout << p->val << "->"; 63 p = p->next; 64 } 65 66 Partition(head, 4); 67 p = head->next; 68 cout << endl << "*******************" << endl << "分部分后的链表为: "; 69 while (p) 70 { 71 cout << p->val << "->"; 72 p = p->next; 73 } 74 cout << endl << "=============================" << endl; 75 }
标签:Node,pr,head,07,左神,next,链表,节点 来源: https://www.cnblogs.com/zzw1024/p/11227973.html