反转链表系列题练习递归
记录学习的三种反转链表
ListNode* reverseList(ListNode* head) {
}
思路:(仅递归)
- 首先,明确函数定义。传入链表头节点,将链表反转后,返回新的头节点。
- 接着,明确如何递归。比如本题就是传入下一个节点即可。
ListNode* newhead = reverseList(head->next);
- 接着,明确操作。也就是说,拿到上一步返回的头节点后该怎么操作?很显然,需要找到反转后链表的尾节点tailNode,然后将tailNode->next = curNode(当前节点);
- 最后,明确个例。个例就是递归终结的情况,不然一直递归。这个题的个例很明确,就是当链表有且仅有一个节点时,直接返回。
if(head->next == nullptr) return head;
- 最最后,明确边界条件/特殊情况。本题只有一个
head==nullptr
ListNode* reverseBetween(ListNode* head, int left, int right) {
}
思路(1):(局部递归)
- 首先,明确函数定义。传入链表头节点,左起、右止的节点个数,反转后返回头节点。
- 接着,明确操作。把[left,right]区间内的节点用 递归方法 反转,记录左起的前一个节点pre,右止的后一个节点post,然后将
pre->next->next = post;
pre->next = newhead;
- 明确个例。这个思路主要是保存pre和post节点,[left,right]区间反转的个例还是单个节点的情况。
思路(2):(整体递归)
- 首先,明确函数定义。传入链表头节点,左起、右止的节点个数,反转后返回头节点。
- 接着,明确怎么递归。传入下个几点,左起数-1,右止数-1。
ListNode* newhead = reverseBetween(head->next, left-1, right-1);
- 接着,明确操作。同样的问题,拿到上一步返回的头节点该怎么操作?只有一个操作,那就是是将当前节点的next指向newhead
head->next = newhead;
- 明确个例。本题个例和边界特殊情况是一样的。我是在处理完边界条件后,才发现这原来是TM个例。
if(left == 1){ }
也就是从第一个node开始反转。这里需要改编反转链表,以前是反转整个list,也就是当head->next==nullptr
的时候return,现在则是当head->next==someoneNode
的时候return。
总结,这道题还是用我自己的思路1比较清晰。
ListNode* reverseKGroup(ListNode* head, int k) {
}
我的思路:
解构题目,K个一组反转list,只需要写个循环,然后每次都调用reverseBetween()
区间反转函数就好啦,这个上面已经写过了。