首页 > 其他分享 >递归反转链表局部[labuladong-刷题打卡 day8]

递归反转链表局部[labuladong-刷题打卡 day8]

时间:2023-08-08 20:45:58浏览次数:37  
标签:head ListNode day8 反转 next 链表 打卡 节点

写在前面

前两天刷题打卡,感觉东哥的代码模板没有题解中的简洁,或者那些极限优化的代码中有很多优化技巧,但今天去感受递归的含义的时候,觉得毕竟我现在是在学习算法,理解算法含义才是学习的意义。至于优化,那是之后的事,所以刷题的时候不必过于追求简洁,就像追求简洁而降低可读性一样属于走火入魔

反转链表除了双指针还有递归,东哥这章的递归反转链表讲解算得上精品之作!

具体讲解原文从:反转链表→反转前N个节点→反转局部链表,已经讲解很清楚了,这里就不画蛇添足,直接简述一下92. 反转链表 II

反转局部链表:Leetcode 92

所谓“迭代是人,递归是神!”,两者都旨在于化问题的解为子问题的解。迭代是由简单解推广到复杂解,递归严格要求父子问题解决方法相同,且需要在得到最小子问题解后倒推原问题解。
分析一下反转问题的递推结构和最小子问题

递推结构

父子问题结构
当我们反转链表N时,其子问题为反转后继N-1链表。
递归假设N-1子问题已经解决时,我们只需考虑如何由规模N-1的子问题得到规模N父问题的解

子问题解决时得到:

  1. 子问题反转后的头节点 [6] :last
  2. 子问题尾节点 [2] next指针: null

    我们由子问题得到父问题的过程为:
  3. 将子问题尾节点[2]→next指向父问题头节点
  4. 父问题头节点→next=null
    至此,父问题由子问题的解得以解决,返回上一级。

基本问题

除了递推结构外,另一个关键问题就是最小子问题或终止递归条件:

  1. 如果是反转全部链表,自然就是检测知道子问题头节点初始next为null
if (head == NULL || head->next == NULL) {
    return head;
}
  1. 如果是反转前N,那就添加一个计数器:n
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;
}
  1. 如果反转局部,就添加两个计数器:m,n
ListNode* reverseBetween(ListNode* head, int m, int n) {
    // base case
    if (m == 1) {
        return reverseN(head, n);
    }
    // 前进到反转的起点触发 base case
    head->next = reverseBetween(head->next, m - 1, n - 1);
    return head;
}

92. 反转链表 II

/**
 * 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; // 后驱节点

// 反转以 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;
    }
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        // base case
        if (left == 1) {
            return reverseN(head, right);
        }
        // 前进到反转的起点触发 base case
        head->next = reverseBetween(head->next, left - 1, right - 1);
        return head;
    }
};

标签:head,ListNode,day8,反转,next,链表,打卡,节点
From: https://www.cnblogs.com/alanjiang/p/17615300.html

相关文章

  • 成功搞定H7-TOO的FreeRTOS Trace图形化链表方式展示任务管理
    之前推出了H7-TOOL的RTOSTrace功能,已经支持RTX5,ThreadX,uCOS-III,uCOS-II和FreeRTOS,特色是不需要目标板额外做任何代码,实时检测RTOS任务执行情况,支持在线和脱机玩法,效果是下面这样的:  这样的展示还不够直观,这几天开始研究图形化链表方式展示任务管理,从源码的角度来看,OS内核......
  • 反转单向链表
    反转单向链表时间复杂度:O(N)空间复杂度:O(1)voidreverse_list(node**head_ptr){ node*prev=NULL; node*curr=*head_ptr; node*next=NULL; while(curr!=NULL){ next=curr->next; curr->next=prev; prev=curr; curr=next; } *head_......
  • 02手写链表
    一、简介手写链表实现以下功能尾插获取指定下标的元素按照指定位置插入元素打印链表内容删除指定元素释放整个链表链表反转链表中相邻元素的和最大的两个元素的第一个节点,且返回和的最大值二、源代码LinkedList.h#ifndef_LINKEDLIST_H#define_LINKEDLIST_H#inc......
  • C语言打卡练习Day4
    1.在一个有序数组中查找具体的某个数字。并将其下标打印出来intmain(){inti=0;intk=5;//要查找的数字intarr[]={1,2,3,4,5,6,7,8,9,10};intnum=sizeof(arr)/sizeof(arr[1]);for(i=0;i<num;i++){if(k==arr[i]){......
  • python对单双链表进行操作
    `classLinkNode:definit(self,val=0,next=None):#定义指针指向节点的数值self.val=val#定义指针self.next=NoneclassMyLinkedList:definit(self):self.head=LinkNode(0)self.size=0#获取链表中下标为index的值,如果下标无效,则返回-1defget(self,index:i......
  • DataWhale NLP第二期 第一次打卡
    理解赛题,跑通竞赛实践全流程跑通实践基线Baseline,获得自己的成绩提交任务一打卡,查看个人成绩排行榜赛题理解赛题链接本赛题要求构建一个文本分类器,来区分真实对话和由AI产生的对话,训练的数据包括一系列真实对话和ChatGPT生成的对话样本,参赛选手需要设计并训练一个模型,使其......
  • 8.6打卡
    L2-012关于堆的判断#include<iostream>#include<stdio.h>#include<vector>#include<cmath>#include<map>#include<algorithm>#include<queue>usingnamespacestd;intn,m,x;intheap[1001];vector<int>a;map<int,int>mp......
  • 24. 两两交换链表中的节点 【递归】
    给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。输入:head=[1,2,3,4]输出:[2,1,4,3] 思路:递归fromtypingimportOptional#创建链表defcreate_linked_list(lst):ifnotlst:......
  • 数据结构与算法(四):双向链表
    基本概念双向链表概念和单向链表是一致的,区别在于双向链表在单向链表的基础上,指针区域多了一个指向上一个节点的指针。单向链表内容可以参考我的上一篇文章:http://t.csdn.cn/Iu56H。基本的数据结构如图所示:链表结构双向链表结构包含了节点的数据内容和两个指针:指向前一个节点......
  • 力扣-24. 两两交换链表中的节点
     题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 =publicstaticListNodeswapPairs(ListNodehead){if(head==null||head.next==null)returnhead;......