算法学习:链表反转
2021-06-13 本文已影响0人
yanlong107
题目1:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
递归解法:
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* last = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return last;
}
};
迭代解法:
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* current = head;
ListNode* ret = nullptr;
ListNode* tmp;
while(current != nullptr) {
tmp = current->next;
current->next = ret;
ret = current;
current = tmp;
}
return ret;
}
};
题目2:
题目:给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* successor = nullptr;
ListNode* reverseN(ListNode* head, int n) {
if (n == 1) {
successor = head->next;
return head;
}
ListNode* last = reverseN(head->next, n -1);
head->next->next = head;
head->next = successor;
return last;
}
ListNode* reverseBetween(ListNode* head, int left, int right) {
if(left == 1) {
return reverseN(head, right);
}
head->next = reverseBetween(head->next, left - 1, right - 1);
return head;
}
};
总结
递归的思路相比迭代,会稍微有点难以理解。 递归和迭代时间复杂度都是o(n), 但是迭代的空间复杂度只有o(1).
递归处理的技巧是: 不要跳进递归,而是利用明确的定义来实现算法逻辑。