解题思路
这是一道链表操作题目,主要思路如下:
-
问题分析:
- 给定一个链表和整数
- 每
个节点为一组进行翻转
- 如果最后剩余节点不足
个,保持原有顺序
- 要求实际交换节点,而不是仅改变值
- 给定一个链表和整数
-
解决方案:
- 使用虚拟头节点简化操作
- 实现单链表翻转的辅助函数
- 按组遍历并翻转链表
- 维护前驱和后继节点的指向关系
-
实现细节:
- 使用三指针法实现链表翻转
- 记录每组翻转的起始和结束位置
- 处理最后一组不足
个节点的情况
代码
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
// 翻转单个链表
ListNode* reverseList(ListNode* head) {
ListNode *prev = nullptr, *curr = head, *next = nullptr;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
// K组翻转
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode *pre = dummy, *end = dummy;
while (end->next) {
// 找到每组的结束位置
for (int i = 0; i < k && end; i++) {
end = end->next;
}
if (!end) break; // 不足k个,结束翻转
// 保存相关节点
ListNode* start = pre->next;
ListNode* next = end->next;
// 断开当前组
end->next = nullptr;
// 翻转当前组并连接
pre->next = reverseList(start);
start->next = next;
// 移动指针到下一组
pre = end = start;
}
ListNode* result = dummy->next;
delete dummy;
return result;
}
};
int main() {
// 读入链表
ListNode* dummy = new ListNode(-1);
ListNode* tail = dummy;
int val;
while (cin >> val) {
tail->next = new ListNode(val);
tail = tail->next;
if (cin.get() == '\n') break;
}
// 读入k
int k;
cin >> k;
// 处理并输出结果
Solution solution;
ListNode* result = solution.reverseKGroup(dummy->next, k);
// 输出结果
while (result) {
cout << result->val;
if (result->next) cout << " ";
result = result->next;
}
cout << endl;
return 0;
}
import java.util.*;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class Main {
// 翻转单个链表
public static ListNode reverseList(ListNode head) {
ListNode prev = null, curr = head, next = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// K组翻转
public static ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy, end = dummy;
while (end.next != null) {
// 找到每组的结束位置
for (int i = 0; i < k && end != null; i++) {
end = end.next;
}
if (end == null) break;
// 保存相关节点
ListNode start = pre.next;
ListNode next = end.next;
// 断开当前组
end.next = null;
// 翻转当前组并连接
pre.next = reverseList(start);
start.next = next;
// 移动指针到下一组
pre = end = start;
}
return dummy.next;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读入链表
ListNode dummy = new ListNode(-1);
ListNode tail = dummy;
String[] nums = sc.nextLine().split(" ");
for (String num : nums) {
tail.next = new ListNode(Integer.parseInt(num));
tail = tail.next;
}
// 读入k
int k = sc.nextInt();
// 处理并输出结果
ListNode result = reverseKGroup(dummy.next, k);
// 输出结果
while (result != null) {
System.out.print(result.val);
if (result.next != null) System.out.print(" ");
result = result.next;
}
System.out.println();
sc.close();
}
}
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def reverse_list(head):
prev = None
curr = head
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
return prev
def reverse_k_group(head, k):
dummy = ListNode(-1)
dummy.next = head
pre = end = dummy
while end.next:
# 找到每组的结束位置
for i in range(k):
end = end.next
if not end:
return dummy.next
# 保存相关节点
start = pre.next
next_node = end.next
# 断开当前组
end.next = None
# 翻转当前组并连接
pre.next = reverse_list(start)
start.next = next_node
# 移动指针到下一组
pre = end = start
return dummy.next
def main():
# 读入链表
nums = list(map(int, input().split()))
dummy = ListNode(-1)
tail = dummy
for num in nums:
tail.next = ListNode(num)
tail = tail.next
# 读入k
k = int(input())
# 处理并输出结果
result = reverse_k_group(dummy.next, k)
# 输出结果
while result:
print(result.val, end='')
if result.next:
print(' ', end='')
result = result.next
print()
if __name__ == "__main__":
main()
算法及复杂度
- 算法:链表操作
- 时间复杂度:
- 每个节点最多被访问两次
- 空间复杂度:
- 只使用常数额外空间