递归魔法:反转单链表 :: 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.
-
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.
-
个人理解 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.
-
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.
-
文章链接点这里:递归魔法:反转单链表
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions