递归魔法:反转单链表 :: labuladong的算法小抄 #994
Replies: 95 comments 16 replies
-
看完了,大魔王到此一游 |
Beta Was this translation helpful? Give feedback.
-
head.next = reverseBetween(head.next, m - 1, n - 1); |
Beta Was this translation helpful? Give feedback.
-
head.next = reverseBetween(head.next, m - 1, n - 1); |
Beta Was this translation helpful? Give feedback.
-
@dullduck |
Beta Was this translation helpful? Give feedback.
-
if (m == 1) { |
Beta Was this translation helpful? Give feedback.
-
@GeorgeSmith215 @dullduck 是这个意思,这是递归对数据结构进行修改的常见操作, |
Beta Was this translation helpful? Give feedback.
-
这递归写得好漂亮 |
Beta Was this translation helpful? Give feedback.
-
讲的真好 |
Beta Was this translation helpful? Give feedback.
-
public static ListNode reverseNM(ListNode current,int n,int m) {
ListNode last = current; // 前一部分的最后一个节点,注意是前一部分,而不是交换部分
while(n>2) {
last = last.next; // 进行条件的设定,因为要记录下第n的前一个,方便链接最后反转后的头节点,要记录下当前的为n==1,前一个为>2
n--;
}
last.next = reverseN(last.next,m-n);
return current;
} 博主你好,请问一下,反转部分链表的时候,直接使用一个迭代,得到需要反转部分的前一个,然后在进行操作,这种方式合理吗,还是按照博主你的来,我发现思路有点混乱 |
Beta Was this translation helpful? Give feedback.
-
标题:“二、反转链表前 N 个节点”最后的代码我认为还可以优化一下 ListNode successor = null; // 后驱节点
// 反转以 head 为起点的 n 个节点,返回新的头结点
ListNode reverseN(ListNode head, int n) {
if (n == 1) {
// 记录第 n + 1 个节点
successor = head.next;
return head;
}
// 以 head.next 为起点,需要反转前 n - 1 个节点
ListNode last = reverseN(head.next, n - 1);
head.next.next = head;
// 让反转之后的 head 节点和后面的节点连起来
head.next = successor;
return last;
} 优化后的代码: // 反转以 head 为起点的 n 个节点,返回新的头结点
ListNode reverseN(ListNode head, int n) {
if (n == 1) {
// 返回最后头节点
return head;
}
// 以 head.next 为起点,需要反转前 n - 1 个节点
ListNode last = reverseN(head.next, n - 1);
/*
这里意思是,head的next指针没有啥用,可以用来记录第n+1个节点,随着递归一直往上传到原来头节点的next。(可以自己画图,比较好理解一点)
*/
ListNode headNext = head.next;
head.next = headNext.next;
headNext.next = head;
return last;
} |
Beta Was this translation helpful? Give feedback.
-
牛蛙 |
Beta Was this translation helpful? Give feedback.
-
太牛了吧 |
Beta Was this translation helpful? Give feedback.
-
理解递归函数的定义并不难,我觉得难点在于,理解它为什么可以做到这样的功能… |
Beta Was this translation helpful? Give feedback.
-
个人理解 class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
last = self.reverseList(head.next)
# 在递归返回的时候,元素“天然”地会倒序弹出
head.next.next = head # 完成head和它后一个节点(head.next)的反转
head.next = None # 原本的下一个节点置空,避免两个节点互为next死循环
return last # 不论当前节点是啥,都返回原本链表的最后一个节点-》也就是反转后的头节点 |
Beta Was this translation helpful? Give feedback.
-
找到递归的base case,通过递归逐步逼近base case |
Beta Was this translation helpful? Give feedback.
-
普通人只会迭代,大神只用递归。哭死 |
Beta Was this translation helpful? Give feedback.
-
怎么写出来这么牛逼的代码? |
Beta Was this translation helpful? Give feedback.
-
C++ 的反转链表2 迭代版: class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode dummy;
dummy.next = head;
ListNode *before = &dummy, *pre = head, *cur = head->next;
for(int i = 1; i < left; i++) {
before = pre;
pre = cur;
cur = cur->next;
}
while(cur != nullptr && left < right) {
left++;
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
before->next->next = cur;
before->next = pre;
return dummy.next;
}
}; |
Beta Was this translation helpful? Give feedback.
-
通过明确递归函数的定义来解决递归问题, 而不要跳进递归,这个思想很有帮助 ! 一旦陷入递归, 思维就很会一团乱麻. |
Beta Was this translation helpful? Give feedback.
-
反转链表前 N 个节点 虽说 if (n == 1) {
// 记录第 n + 1 个节点
successor = head.next;
return head;
} 只有跳进递归才能理解 后来转念一想, 对递归的理解又加深了一点:v: |
Beta Was this translation helpful? Give feedback.
-
666,这个大boss的往前走的思想真的不容易想出来啊 |
Beta Was this translation helpful? Give feedback.
-
引用原文:迭代实现思路看起来虽然简单,但是细节问题很多的,反而不容易写对。 |
Beta Was this translation helpful? Give feedback.
-
哈哈,一开始不会迭代反转单链表,又去查了一下。现在两者皆会了。 |
Beta Was this translation helpful? Give feedback.
-
beautiful |
Beta Was this translation helpful? Give feedback.
-
真烧脑,看了两遍还懵懵懂懂,我太菜了😭 |
Beta Was this translation helpful? Give feedback.
-
Day2打卡! |
Beta Was this translation helpful? Give feedback.
-
92.反转链表Python版本打卡 class Solution:
def __init__(self):
self.successor=ListNode()
def reverseN(self,head: Optional[ListNode],n):
if n==1:
self.successor=head.next
return head
last=self.reverseN(head.next,n-1)
head.next.next=head
head.next=self.successor
return last
def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
if not head or not head.next:
return head
if left==1:
return self.reverseN(head,right)
head.next=self.reverseBetween(head.next,left-1,right-1)
return head |
Beta Was this translation helpful? Give feedback.
-
反转链表前N个结点不需额外记录后继结点的写法 func reverseN(head *ListNode, n int) *ListNode {
if n == 1 { //base case
return head
}
reverseHead := reverseN(head.Next, n-1)
tmp := head.Next.Next
head.Next.Next = head
head.Next = tmp
return reverseHead
} |
Beta Was this translation helpful? Give feedback.
-
感觉可以使用链表的头插法用来翻转链表吧,如果使用头插法,仅需一个for循环,而不用递归。 |
Beta Was this translation helpful? Give feedback.
-
ListNode reverseN(ListNode head, int n) {
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:递归魔法:反转单链表
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions