笨方案一:利用线性表存储该链表,而后直接按顺序访问指定元素,重建该链表即可。
void reorderList(ListNode* head) {
if(head == nullptr) return;
vector<ListNode*> vec;
while(head != nullptr){
vec.push_back(head);
head = head->next;
}
int i = 0;
int j = vec.size() - 1;
while(i < j){
vec[i]->next = vec[j];
++i;
if (i == j) {
break;
}
vec[j]->next = vec[i];
--j;
}
vec[i]->next = nullptr;
}
方案二:寻找链表中点 + 链表逆序 + 合并链表
注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。
这样任务可划分为三步:
使用迭代法实现链表的反转。
class Solution {
public:
void reorderList(ListNode* head) {
if(head == nullptr) return;
ListNode* mid = middleNode(head);
ListNode* reverse = reverseList(mid->next);
mid->next = nullptr; // 将链表切断
mergeList(head, reverse);
}
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast->next != nullptr && fast->next->next != nullptr){
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = nullptr;
while(cur != nullptr){
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
void mergeList(ListNode* l1, ListNode* l2) {
while(l2 != nullptr){
ListNode* templ1 = l1->next;
l1->next = l2;
l1 = templ1;
ListNode* templ2 = l2->next;
l2->next = l1;
l2 = templ2;
}
}
};
与21相同的思路代码如下,注意返回值为ListNode*了
ListNode* mergeList(ListNode* l1, ListNode* l2) {
ListNode* dummyhead = new ListNode(999);
ListNode* cur = dummyhead;
while(l1 != nullptr && l2 != nullptr){
cur->next = l1;
l1 = l1->next;
cur = cur->next;
cur->next = l2;
l2 = l2->next;
cur = cur->next;
}
if(l1 != nullptr) cur->next = l1;
if(l2 != nullptr) cur->next = l2;
return dummyhead->next;
}
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(list1 == nullptr) return list2;
if(list2 == nullptr) return list1;
ListNode* dummyhead = new ListNode(0);
ListNode* cur = dummyhead;
while(list1 != nullptr && list2 != nullptr) {
if(list1->val < list2->val){
cur->next = list1;
cur = cur->next;
list1 = list1->next;
}else{
cur->next = list2;
cur = cur->next;
list2 = list2->next;
}
}
if(list1 != nullptr) cur->next = list1;
if(list2 != nullptr) cur->next = list2;
return dummyhead->next;
}
while的退出条件是画图得出的
ListNode* oddEvenList(ListNode* head) {
if(head == nullptr) return head;
ListNode* odd = head;
ListNode* even = head->next;
ListNode* evenhead = even;
while(even != nullptr && even->next != nullptr) {
odd->next = even->next; // 1
even->next = odd->next->next; // 2
odd = odd->next;
even = even->next;
}
odd->next = evenhead;
return head;
}
#include
using namespace std;
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode* next;
ListNode(int val)
: val(val)
, next(nullptr)
{}
};
MyLinkedList() {
node_ = new ListNode(0);
size_ = 0;
}
int get(int index) {
if (index >= size_ || index < 0) return -1;
ListNode* cur = node_;
while (index--) {
cur = cur->next;
}
cur = cur->next;
return cur->val;
}
void addAtHead(int val) {
ListNode* newNode = new ListNode(val);
newNode->next = node_->next;
node_->next = newNode;
size_++;
}
void addAtTail(int val) {
ListNode* newNode = new ListNode(val);
ListNode* cur = node_;
while (cur->next != nullptr) {
cur = cur->next;
}
cur->next = newNode;
size_++;
}
void addAtIndex(int index, int val) {
if (index > size_ || index < 0) return; // index可以为size_
ListNode* newNode = new ListNode(val);
ListNode* cur = node_;
while (index--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size_++;
}
void deleteAtIndex(int index) {
if (index >= size_ || index < 0) return;
ListNode* cur = node_;
while (index--) {
cur = cur->next;
}
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
size_--;
}
void show() {
ListNode* cur = node_->next;
while (cur != nullptr) {
cout << cur->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int size_;
ListNode* node_;
};
int main() {
MyLinkedList link;
link.addAtHead(7);
link.addAtHead(2);
link.addAtHead(1);
link.addAtTail(8);
link.show();
link.deleteAtIndex(2);
link.show();
return 0;
}
#include
using namespace std;
struct Node {
int data_;
Node* pre_;
Node* next_;
Node(int data)
: data_(data)
, pre_(nullptr)
, next_(nullptr)
{}
Node()
{
pre_ = nullptr;
next_ = nullptr;
}
};
class DoubleLink {
public:
DoubleLink() {
head_ = new Node();
}
~DoubleLink() {
Node* p = head_;
while (p != nullptr) {
head_ = head_->next_;
delete p;
p = head_;
}
}
public:
void insert_head(int val) {
Node* node = new Node(val);
node->next_ = head_->next_;
node->pre_ = head_;
if (head_->next_ != nullptr) head_->next_->pre_ = node; //原来链表里有第一个节点 确认head后面一个不为空
head_->next_ = node;
}
// 尾插法
void InsertTail(int val) {
Node* p = head_;
while (p->next_ != nullptr) {
p = p->next_;
}
Node* node = new Node(val);
node->pre_ = p;
p->next_ = node;
}
void Remove(int val) {
Node* p = head_->next_;
while (p != nullptr) {
if (p->data_ == val) {
p->pre_->next_ = p->next_;
if (p->next_ != nullptr) p->next_->pre_ = p->pre_;
delete p;
return;
} else {
p = p->next_;
}
}
}
bool Find(int val) {
Node* p = head_->next_;
while (p != nullptr) {
if (p->data_ == val) {
return true;
} else {
p = p->next_;
}
}
}
void show() {
Node* p = head_->next_;
while (p != nullptr) {
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
}
private:
Node* head_;
};
int main() {
DoubleLink dlink;
dlink.InsertTail(20);
dlink.InsertTail(23);
dlink.InsertTail(89);
dlink.InsertTail(15);
dlink.InsertTail(36);
dlink.InsertTail(78);
dlink.InsertTail(56);
dlink.InsertTail(41);
dlink.InsertTail(32);
dlink.show();
dlink.insert_head(200);
dlink.show();
dlink.Remove(200);
dlink.show();
dlink.Remove(78);
dlink.show();
return 0;
}
#include
using namespace std;
struct Node {
int data_;
Node* pre_;
Node* next_;
Node(int data)
: data_(data)
, pre_(nullptr)
, next_(nullptr)
{}
Node()
{
pre_ = nullptr;
next_ = nullptr;
}
};
class DoubleCircleLink {
public:
DoubleCircleLink() {
head_ = new Node();
head_->next_ = head_;
head_->pre_ = head_;
}
~DoubleCircleLink() {
Node* p = head_->next_;
while (p != head_) {
head_->next_ = p->next_;
p->next_->pre_ = head_;
delete p;
p = head_->next_;
}
delete head_;
head_ = nullptr;
}
public:
void insert_head(int val) {
Node* node = new Node(val);
node->next_ = head_->next_;
node->pre_ = head_;
if (head_->next_ != nullptr) head_->next_->pre_ = node; //原来链表里有第一个节点 确认head后面一个不为空
head_->next_ = node;
}
// 尾插法
void InsertTail(int val) {
Node* p = head_->pre_;
Node* node = new Node(val);
node->pre_ = p;
p->next_ = node;
node->next_ = head_;
head_->pre_ = node;
}
void Remove(int val) {
Node* p = head_->next_;
while (p != head_) {
if (p->data_ == val) {
p->pre_->next_ = p->next_;
p->next_->pre_ = p->pre_;
delete p;
return;
} else {
p = p->next_;
}
}
}
bool Find(int val) {
Node* p = head_->next_;
while (p != head_) {
if (p->data_ == val) {
return true;
} else {
p = p->next_;
}
}
}
void show() {
Node* p = head_->next_;
while (p != head_) {
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
}
private:
Node* head_;
};
int main() {
DoubleCircleLink dlink;
dlink.InsertTail(20);
dlink.InsertTail(23);
dlink.InsertTail(89);
dlink.InsertTail(15);
dlink.InsertTail(36);
dlink.InsertTail(78);
dlink.InsertTail(56);
dlink.InsertTail(41);
dlink.InsertTail(32);
dlink.show();
dlink.insert_head(200);
dlink.show();
dlink.Remove(200);
dlink.show();
dlink.Remove(78);
dlink.show();
return 0;
}
感谢博主 @-特立独行的猪-
实在是太强了555