-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlistPartition.h
More file actions
150 lines (139 loc) · 4.71 KB
/
listPartition.h
File metadata and controls
150 lines (139 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//
// listPartition.h
// linkedList
//
// Created by junl on 2019/11/11.
// Copyright © 2019 junl. All rights reserved.
//
#ifndef listPartition_hpp
#define listPartition_hpp
#include <stdio.h>
#include "creatlist.h"
#include <stack>
/*
将单向链表按某值划分成左边小,中间相等,右边大的形式.除了这个要求外,对调整后的节点顺序没有更多的要求.
进阶问题:
1. 在左中右三个部分的内部也要做顺序要求,要求每个部分和之前链表中节点的先后次序一致.
2. 如果链表长度为N,时间复杂度请打到O(N),额外空间复杂度请打到O(1)
*/
namespace itinterviews {
class listPartition{
public:
/*
思路:首先将所有节点放入到一个数组中,然后对数组进行排序:
小的放左边,大的防右边,最后把他们连接起来
*/
ListNode *solve(ListNode *head, int pivot){
if (head == nullptr)
return head;
//获取链表长度,构建节点数组
int len = 0;
ListNode *node = head;
while (node) {
len++;
node = node->next;
}
ListNode* nodes[len];
node = head;
for (int i=0; i<len; i++) {
nodes[i] = node;
node = node->next;
}
//对其排序
sort(nodes, len, pivot);
//最后把所有节点连接起来
int i=0;
for (; i<len-1; i++) {
nodes[i]->next = nodes[i+1];
}
nodes[i]->next = nullptr;
return nodes[0];
}
private:
void sort(ListNode* nodes[], int len, int pivot){
int index,start,end;
index = 0;
start = -1;
end = len;
//小的放左边,相等的不变,大的放右边
while (index != end) {
if (nodes[index]->val > pivot) {
swap(nodes, index, --end);
}else if (nodes[index]->val == pivot){
index++;
}else{
swap(nodes, index++, ++start);
}
}
}
void swap(ListNode* nodes[],int a, int b){
ListNode *tmp = nodes[a];
nodes[a] = nodes[b];
nodes[b] = tmp;
for (int i =0; i< 5; i++) {
std::cout << nodes[i]->val << ", ";
}
std::cout << std::endl;
}
};
class listPartition_advance{
public:
/*
思路:
进阶问题:将链表分为三个子链表,最后链接起来即可
*/
ListNode *solve(ListNode *head, int pivot){
if (head == nullptr)
return head;
ListNode *smallhead,*smalltail,*equalhead,*equaltail,*bighead,*bigtail;
smallhead = smalltail = nullptr;
equalhead = equaltail = nullptr;
bighead = bigtail = nullptr;
ListNode *next;
while (head) {
next = head->next;
head->next=nullptr;
if (head->val < pivot) {
if (!smallhead){
smallhead = smalltail = head;
}else{
smalltail->next = head;
smalltail = head;
}
}else if (head->val == pivot){
if (!equalhead){
equalhead =equaltail = head;
}else{
equaltail->next = head;
equaltail = head;
}
}else{
if (!bighead){
bighead = bigtail = head;
}else{
bigtail->next = head;
bigtail = head;
}
}
head = next;
}
if (smalltail){
smalltail->next = equalhead;
equaltail = equaltail ?: smalltail;
}
if (equaltail){
equaltail->next = bighead;
}
return smallhead ?: (equalhead?:bighead);
}
};
void test_listPartition(){
std::cout << "----将单向链表按某值划分成左边小,中间相等,右边大的形式----" << std::endl;
ListNode *head = codinginterviews::creatLists({9,0,4,5,1})->next;
// class listPartition so;
class listPartition_advance so;
head = so.solve(head, 4);
head->print();
}
}
#endif /* listPartition_hpp */