题目描述
给你单链表的头节点 head,请你反转链表,并返回反转后的链表的头节点。
输入格式
输入共 2 行:
- 第一行包含一个整数 n,表示链表的长度。
- 第二行包含 n 个整数,表示链表的节点值,按链表顺序给出。
输出格式
输出共 1 行,包含 n 个整数,表示反转后的链表的节点值,按链表顺序给出。
数据范围
链表中节点的数目在范围 [0, 5000] 内
-5000 ≤ Node.val ≤ 5000
输入样例1:
输出样例1:
输入样例2:
输出样例2:
输入样例3:
输出样例3:
注意事项
- 可以使用迭代或递归的方法来反转链表。
- 迭代方法的时间复杂度为O(n),空间复杂度为O(1)。
- 递归方法的时间复杂度为O(n),空间复杂度为O(n),因为递归调用会使用栈空间。
- 在本题中,为了方便输入输出,我们将使用数组来模拟链表的输入,并将反转后的链表转换为数组输出。
代码实现
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
| #include <iostream> #include <vector> using namespace std;
struct ListNode { int val; ListNode *next; ListNode() : val(0), next(nullptr) {} ListNode(int x) : val(x), next(nullptr) {} ListNode(int x, ListNode *next) : val(x), next(next) {} };
ListNode* reverseListIterative(ListNode* head) { ListNode* prev = nullptr; ListNode* curr = head; while (curr != nullptr) { ListNode* nextTemp = curr->next; curr->next = prev; prev = curr; curr = nextTemp; } return prev; }
ListNode* reverseListRecursive(ListNode* head) { if (head == nullptr || head->next == nullptr) { return head; } ListNode* newHead = reverseListRecursive(head->next); head->next->next = head; head->next = nullptr; return newHead; }
ListNode* createList(vector<int>& nums) { if (nums.empty()) { return nullptr; } ListNode* head = new ListNode(nums[0]); ListNode* current = head; for (int i = 1; i < nums.size(); i++) { current->next = new ListNode(nums[i]); current = current->next; } return head; }
vector<int> listToArray(ListNode* head) { vector<int> result; ListNode* current = head; while (current != nullptr) { result.push_back(current->val); current = current->next; } return result; }
void deleteList(ListNode* head) { ListNode* current = head; while (current != nullptr) { ListNode* next = current->next; delete current; current = next; } }
int main() { int n; cin >> n; vector<int> nums(n); for (int i = 0; i < n; i++) { cin >> nums[i]; } ListNode* head = createList(nums); ListNode* reversedHead = reverseListIterative(head); vector<int> result = listToArray(reversedHead); for (int i = 0; i < result.size(); i++) { cout << result[i]; if (i != result.size() - 1) { cout << " "; } } cout << endl; deleteList(reversedHead); return 0; }
|
时间复杂度
- 迭代方法时间复杂度:O(n),其中 n 是链表的长度。我们只需要遍历链表一次。
- 递归方法时间复杂度:O(n),其中 n 是链表的长度。递归调用的次数等于链表的长度。
- 空间复杂度:O(1)(迭代方法)或 O(n)(递归方法,由递归调用栈占用的空间)。
代码解释
- 反转链表是链表操作中的一个基础问题,可以用迭代或递归的方法解决。
- 迭代方法的核心思想是维护三个指针:prev(前一个节点)、curr(当前节点)和nextTemp(下一个节点)。在遍历链表的过程中,我们将当前节点的next指针指向前一个节点,然后移动这三个指针,直到遍历完整个链表。
- 递归方法的核心思想是先递归反转链表的剩余部分,然后反转当前节点和下一个节点的连接。递归的基本情况是空链表或只有一个节点的链表。
- 在本题中,为了方便输入输出,我们使用数组来模拟链表的输入,并将反转后的链表转换为数组输出。在实际应用中,链表通常是直接给定的。