一道腾讯面试题——逆序K链表反转
腾讯CSIG腾讯云数据库内核方向-分布式存储,初试算法题
题目
给定如下单链表节点定义:
struct node {
struct node* next_;
int val_;
};
给定一个单链表,指定一个整数i,从链表尾部算起,以i个节点为一组进行链表反转操作。组之间保持原链接顺序。如果不够i个节点,也不反转。例如:
原链表为:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
指定整数3。则结果链表为:
1 -> 2 -> 5 -> 4 -> 3 -> 8 -> 7 -> 6
是不是很简单,Leetcode经典题,K链表反转,只不过这个是从后往前
方法一:每K个反转
先求出长度,算出可能剩余的部分,跳过开头这部分,对接下来的反转
(1 2) 3 4 5 6 7 8
点击查看代码
#include <iostream>
using namespace std;
struct node {
struct node* next_;
int val_;
node(int val):next_(nullptr), val_(val) {}
};
int countNode(node* head) {
int cnt = 0;
node* cur = head;
while(cur) {
cnt++;
cur = cur->next_;
}
return cnt;
}
node* reverseK(node* head, int k) { // 每k个反转一次
if(head == nullptr) return nullptr;
cout << "head: " << head->val_ << endl; // 有
int cnt = 0;
node* cur = head, *pre = nullptr, *nxt;
while(cur && cnt < k) {
cout << "cnt: " << cnt << " " << cur->val_ << endl;
nxt = cur->next_;
cur->next_ = pre;
pre = cur;
cur = nxt;
cnt++;
}
// cout << "cur: " << cur->val_ << endl;
head->next_ = reverseK(cur, k);
return pre; //太惨吧,改这一个地方就行了
}
node* reverseList(node* head, int k) {
int len = countNode(head);
int last = len % k;
int cnt = 0;
node* cur = head, *pre;
while(cnt < last) {
cnt++;
pre = cur;
cur = cur->next_;
}
cout << "cur: " << cur->val_ << endl; // ok
pre->next_ = reverseK(cur, k);
return head;
}
node* createList(int n, int k) {
node* head = new node(0);
node* cur = head;
for(int i = 1;i <= n;i++) {
cur->next_ = new node(i);
cur = cur->next_;
}
return head->next_;
}
void printList(node* head) {
node* cur = head;
while(cur) {
cout << cur->val_ << " ";
cur = cur->next_;
}
cout << endl;
}
int main() {
//int a;
//cin >> a;
cout << "Hello World!" << endl;
node* head = createList(8, 3);
printList(head);
head = reverseList(head, 3);
printList(head);
}
方法二:先整体反转,在以K个为一组反转
有点像“单词翻转”的思路,翻转两次
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1
(8 7 6) (5 4 3) (2 1)
(2 1) (5 4 3) (8 7 6)
点击查看代码
#include <iostream>
using namespace std;
struct node {
struct node* next_;
int val_;
node(int val):next_(nullptr), val_(val) {}
};
int countNode(node* head) {
int cnt = 0;
node* cur = head;
while(cur) {
cnt++;
cur = cur->next_;
}
return cnt;
}
node* reverseAll(node* head) { // 反转链表
node* cur = head, *pre = nullptr, *nxt;
while(cur) {
nxt = cur->next_;
cur->next_ = pre;
pre = cur;
cur = nxt;
}
return pre;
}
node* reverseList(node* head, int k) { // 逆序K链表反转
node* dummy = new node(0);
head = reverseAll(head);
node* cur = head, *left = head, *prev;
while(cur) {
int cnt = 0;
while(cur && cnt < k) { // [left, prev] 为一个组
cnt++;
prev = cur;
cur = cur->next_;
}
node* nxt = dummy->next_; // 每次头插法,插入一个组
dummy->next_ = left;
prev->next_ = nxt;
left = cur;
}
return dummy->next_;
}
node* createList(int n, int k) {
node* head = new node(0);
node* cur = head;
for(int i = 1;i <= n;i++) {
cur->next_ = new node(i);
cur = cur->next_;
}
return head->next_;
}
void printList(node* head) {
node* cur = head;
while(cur) {
cout << cur->val_ << " ";
cur = cur->next_;
}
cout << endl;
}
int main() {
//int a;
//cin >> a;
cout << "Hello World!" << endl;
node* head = createList(8, 3);
printList(head);
head = reverseList(head, 3);
printList(head);
}
个性签名:时间会解决一切