Problem
给定一个链表,如 1->2->3->4->5->6,指定k = 4(表示第4个节点),则翻转后的效果为 5->6->4->1->2->3。
Solution
根据示例,题意其实就很简单了,以第k个节点(称为‘界限节点’)为界限分为两段,前一段换到界限节点后面,后一段换到界限节点的前面。
Codes
核心算法部分:
Node* reverse(Node* head, int k) {
if (head == nullptr || k < 1)
return head;
Node* dummyNode = new Node(-1, head);
Node* p = dummyNode;
--k;// k 的值减一
while (k--) {
p = p->next;
}
//现在p节点指向了 分割节点的前一个节点
Node* newHead = p->next->next;//分割节点的后一个节点成为新的头节点
p->next->next = head;
Node* cur = newHead;
while (cur && cur->next) {//你加个
cur = cur->next;
}
//cur指针走到newHead链表的倒数第一个节点
cur->next = p->next;//后面的一段与前面的接起来
p->next = nullptr;//原来前一段的最后一个节点的指向置空
return newHead;
}
全部代码(可以测试):
#include<iostream>
#include <vector>
using namespace std;
struct Node {
int val;
Node* next;
Node(int _val, Node* _next) :val(_val), next(_next) {}
};
Node* reverse(Node* head, int k) {
if (head == nullptr || k < 1)
return head;
Node* dummyNode = new Node(-1, head);
Node* p = dummyNode;
--k;// k 的值减一
while (k--) {
p = p->next;
}
//现在p节点指向了 分割节点的前一个节点
Node* newHead = p->next->next;//分割节点的后一个节点成为新的头节点
p->next->next = head;
Node* cur = newHead;
while (cur && cur->next) {//你加个
cur = cur->next;
}
//cur指针走到newHead链表的倒数第一个节点
cur->next = p->next;//后面的一段与前面的接起来
p->next = nullptr;//原来前一段的最后一个节点的指向置空
return newHead;
}
Node* createList(vector<int>& nodes) {
Node* head = new Node(nodes[0], nullptr);
Node* cur = head;
for (int i = 1; i < nodes.size(); ++i) {
cur->next = new Node(nodes[i], nullptr);
cur = cur->next;
}
return head;
}
void print(Node* head) {
while (head) {
cout << head->val << " -> ";
head = head->next;
}cout << "nullptr";
}
int main() {
vector<int> nodes{ 1,2,3,4,5,6 };
auto head = createList(nodes);
head = reverse(head, 4);
print(head);
return 0;
}