leetcode刷题详解三

news2024/11/18 15:50:11
2. 两数相加

思路:直接加,注意进位条件不要用if,核心代码在于sum = l1->val + l2->val + carry;

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* dummy = new ListNode();
        ListNode* dummy_head = dummy;
        int carry = 0;
        int sum = 0;
        int single = 0;
        while(l1 && l2){
            sum = l1->val + l2->val + carry;
            carry = sum / 10;
            single = sum % 10;
            ListNode* node = new ListNode(single);
            dummy -> next = node;
            dummy = dummy->next;
            l1 = l1->next;
            l2 = l2->next;
        }
        while(l1){
            sum = l1->val + carry;
            carry = sum / 10;
            single = sum % 10;
            ListNode* node = new ListNode(single);
            dummy -> next = node;
            dummy = dummy->next;
            l1 = l1->next;
        }
        while(l2){
            sum = l2->val + carry;
            carry = sum / 10;
            single = sum % 10;
            ListNode* node = new ListNode(single);
            dummy -> next = node;
            dummy = dummy->next;
            l2 = l2->next;
        }
        if(carry){
            ListNode* node = new ListNode(carry);
            dummy -> next = node;
            dummy = dummy->next;
        }
        return dummy_head->next;
    }
445. 两数相加 II

思路:用栈,这样如果两个链表长度不相等的时候不用那么麻烦。

难点在于代码的细节控制。

  1. 当代码中出现空栈时候,则对应的数置为0,不要再写if判断了。
  2. 用第三个栈重建一个链表,这样耗费空间。可以参考第一种写法,总之这道题在于细节控制,思想上不难。
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        stack<int> s1;
        stack<int> s2;
        int carry = 0;
        int sum = 0;
        int single = 0;
        ListNode* dummy = new ListNode();
        ListNode* dummy_head = dummy;

        while(l1){
            s1.push(l1->val);
            l1=l1->next;
        }
        while(l2){
            s2.push(l2->val);
            l2 = l2->next;
        }
        
        while(!s1.empty() && !s2.empty()){
            sum  = s1.top() + s2.top() + carry;
            single = sum % 10;
            carry = sum / 10;
            ListNode * tmp = new ListNode(single);
            dummy -> next = tmp;
            dummy = dummy->next;
            s1.pop();
            s2.pop();
        }
        while(!s1.empty()){
            sum  = s1.top() + carry;
            single = sum % 10;
            carry = sum / 10;
            ListNode * tmp = new ListNode(single);
            dummy -> next = tmp;
            dummy = dummy->next;
            s1.pop();
        }
        while(!s2.empty()){
            sum  = s2.top() + carry;
            single = sum % 10;
            carry = sum / 10;
            ListNode * tmp = new ListNode(single);
            dummy -> next = tmp;
            dummy = dummy->next;
            s2.pop();
        }
        if(carry){
            ListNode * tmp = new ListNode(carry);
            dummy -> next = tmp;
            dummy = dummy->next;
        }

        ListNode* reverse_head = reverse(dummy_head->next);
        return reverse_head;
    }

    ListNode* reverse(ListNode* node){
        if(!node || !node->next){
            return node;
        }
        ListNode* tmp = reverse(node->next);
        node->next->next = node;
        node->next = nullptr;
        return tmp;
    }
725. 分隔链表

思路:这道题就是先求出链表长度,然后分段。

主要难点在于断链,vector每一个索引都是一个链表,在锻炼表操作这里我足足困了好长时间

其实重点就两句话:dummy = root;
root = root->next;(这个代码是设置前置节点的最好办法)

因为我们要找到前置节点,其实很简单dummy = root 中dummy就可以变成前置节点了!!!

vector<ListNode*> splitListToParts(ListNode* root, int k) {        
    //计算长度        
    int length = 0;        
    ListNode* temp = root;        
    while(temp){            
        length++;            
        temp = temp->next;        
    }        
    //每个断链的长度        
    int arry_len = (length / k) > 0 ? (length / k) : 1;        
    int arry[k];        
    for(int i = 0;i < k; i++){            
        arry[i] = arry_len;        
    }        
    //因为长度差不超过一,因此根据length和k*arry_len的差依次给前面的每个值+1        
    int gap = 0;        
    if((k * arry_len) < length){            
        gap = length - (k * arry_len);            
        for(int i = 0;i < gap;i++){                
            arry[i]++;            
        }        
    }                
    //断链表操作        
    vector<ListNode*> splict;        
    ListNode* dummy ;        
    for(int i = 0; i < k; i++){            
        splict.push_back(root);            
        for(int j = 0;j < arry[i];j++){                
            if(root){                    
                dummy = root;/*前置结点的精髓所在*/                    
                root = root->next;                
            }                          
        }
        if(dummy){                    
             dummy->next = NULL;                
        }  
    }        
    return splict;    
}
328. 奇偶链表

双指针然后拼接

ListNode* oddEvenList(ListNode* head) {
    if(!head || !head->next || !head->next->next){
        return head;
    }
    ListNode* odd = head;
    ListNode* even = head->next;
    ListNode* dummy = even;
    while(odd->next && even->next){
        odd->next = even->next;
        odd = odd->next;
        even->next = odd->next;
        even = even->next;
    }
    odd->next = dummy;
    return head;
}
⭕️92. 反转链表 II

反转链表精髓:

image

关于反转链表相关的递归思想,看这个

这个反转链表,思想和反转前n个链表一模一样。

只不过,第一个left不是从1开始反转,那又如何?我们可以让他变成从1开始,想一想。

反转前n个链表

img
ListNode* temp = nullptr;
    ListNode* reverseN(int n,ListNode* node){
        if(n == 1){
            temp = node->next;
            return node;
        }

        ListNode* last = reverseN(n-1, node->next);
        node->next->next = node;
        node->next = temp;
        return last;
    }

这道题解,递归解法----反转链表递归解法还是比较简单的

ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode* dummy = head;
        ListNode* n1 = nullptr;
        int length = right - left +1;
        while(left > 1){
            n1 = dummy;/*记录前一个节点*/
            dummy = dummy->next;
            left--;
        }
        ListNode* n2 = reverseN(length, dummy);
    	//n1为空说明left就是1,从第一个位置反转的!!!
        if(n1){
            n1->next = n2;
        }else{
            return n2;
        }
        return head;
    }

    ListNode* temp = nullptr;
    ListNode* reverseN(int n,ListNode* node){
        if(n == 1){
            temp = node->next;
            return node;
        }

        ListNode* last = reverseN(n-1, node->next);
        node->next->next = node;
        node->next = temp;
        return last;
    }

/*******************第二种解法***********************/
/*有两个dummy节点,begin前和end后,因此要判断四次*/
ListNode* reverseBetween(ListNode* head, int left, int right) {
    if(!head || !head->next){
        return head;
    }
    ListNode* begin = head;
    ListNode* end = head;
    ListNode* dummy = nullptr;
    while(left > 1){
        dummy = begin;
        begin = begin->next;
        left--;
    }
    while(right > 1){
        end = end->next;
        right--;
    }
    ListNode* dummy2 = end->next;
    ListNode* node = reverse(begin, end);
    if(!dummy && !dummy2){
        cout<<"1"<<endl;
        return end;
    }
    else if(!dummy && dummy2){
        cout<<"2"<<endl;
        begin->next = dummy2;
        return end;
    }
    else if(dummy && !dummy2){
        cout<<"3"<<endl;
        dummy->next = end;
        return head;
    }
    cout<<"4"<<endl;
    dummy->next = node;
    begin->next = dummy2;
    return head;
}

ListNode* reverse(ListNode* begin, ListNode* end){
    if(begin == end){
        return begin;
    }
    ListNode* tmp = reverse(begin->next, end);
    begin->next->next = begin;
    begin->next = nullptr;
    return tmp;
}
83. 删除排序链表中的重复元素
b805fe719e7b0bce53d3e78d4575ed3

思路如图所示,很好理解。

ListNode* deleteDuplicates(ListNode* head) {
        if(!head || !head->next){
            return head;
        }
        int value = head->val;
        ListNode* temp = head->next;
        ListNode* carry = head;
        while(temp){
            if(temp->val == value){
                ListNode* dummy = temp;
                temp = temp->next;
                carry->next = temp;
                delete dummy;
                dummy = nullptr;
            }else{
                carry = carry->next;
                value = carry->val;
                temp = temp->next;
            }
        }
        return head;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1249960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OSG编程指南<十>:OSG几何体的绘制

1、场景基本绘图类 在 OSG 中创建几何体的方法比较简单&#xff0c;通常有 3 种处理几何体的手段&#xff1a; 使用松散封装的OpenGL 绘图基元&#xff1b;使用 OSG 中的基本几何体&#xff1b;从文件中导入场景模型。 使用松散封装的OpenGL 绘图基元绘制几何体具有很强的灵活…

完美解决:vue.js:6 TypeError: Cannot read properties of undefined (reading ‘0‘)

Vue项目出现以下报错&#xff1a; 原因&#xff1a; 在渲染的时候&#xff0c;不满足某个条件而报错&#xff0c;或者某个属性丢失或后台没传过来导致 我这里出现的原因是后台给我传递过来的数组中&#xff0c;其中有一条少传了一个我在渲染时需要用的属性&#xff0c;没让后台…

毅速:3D打印随形透气钢为解决模具困气提供了新助力

在模具行业中&#xff0c;困气是一个较常见的问题。解决困气问题的方法有很多&#xff0c;透气钢就是其一。传统的制造的透气钢往往存在一些不足&#xff0c;如加工难度大、无法满足复杂形状的需求等。随着3D打印技术的发展&#xff0c;一种新型的随形透气钢技术逐渐崭露头角&a…

HBase数据模型杂谈

1.概述 HBase是一个稀疏、多维度、排序的映射表&#xff0c;这张表的索引是行键、列族、列限定符和时间戳。 每个值是一个未经解释的字符串&#xff0c;没有数据类型。用户在表中存储数据&#xff0c;每一行都有一个可排序的行键和任意多的列。表在水平方向由一个或者多个列族…

【Jenkins】jenkins发送邮件报错:Not sent to the following valid addresses:

jenkins报错未能发送邮件到指定邮箱 注意&#xff1a;这是在系统配置中修改 在系统配置》邮件通知中添加配置信息 注意&#xff1a;这个是在项目的配置下修改 配置完成后&#xff0c;重新执行发送邮件成功&#xff01;&#xff01;&#xff01;

AI动画制作 StableDiffusion

1.brew -v 2.安装爬虫项目包所必需的python和git等系列系统支持部件 brew install cmake protobuf rust python3.10 git wget pod --version brew link --overwrite cocoapods 3.从github网站克隆stable-diffusion-webui爬虫项目包至本地 ssh-add /Users/haijunyan/.ssh/id_rs…

API 设计:使用 Node.js 和 Express.js 的综合教程

API&#xff08;应用程序编程接口&#xff09;设计涉及创建一个高效而强大的接口&#xff0c;允许不同的软件应用程序相互交互。 说明 本教程将指导您使用 Node.js 和 Express.js 作为核心技术来规划、设计和构建 API。但是&#xff0c;这些原则可以应用于任何语言或框架。我们…

NX二次开发UF_CURVE_ask_curve_inflections 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_curve_inflections Defined in: uf_curve.h int UF_CURVE_ask_curve_inflections(tag_t curve_eid, double proj_matrx [ 9 ] , double range [ 2 ] , int * num_infpt…

手写一个简单版的Spring

1. 创建一个工程及初始化 创建Java工程 创建对应的包 config&#xff1a;为配置类包 service&#xff1a;定义的将要被自己写的Spring容器管理的组件bean spring&#xff1a;里面定义自己写的Spring的类文件&#xff0c;包含子包anno注解包 test&#xff1a;定义测试类 2.…

生物识别访问面临风险

安全公司 Blackwing Intelligence 发现了多个允许您绕过Windows Hello 身份验证的漏洞。 戴尔 Inspiron 灵越 15、联想 ThinkPad T14 和 Microsoft Surface Pro X笔记本电脑上会出现这种情况&#xff0c;原因是设备中集成了来自Goodix、Synaptics 和 ELAN的指纹传感器。 所有…

C#,数值计算——插值和外推,Powvargram的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Functor for variogram v(r)ar^b, /// where b is specified, a is fitted from the data. /// </summary> public class Powvargram { private do…

情感对话机器人的任务体系

人类在处理对话中的情感时&#xff0c;需要先根据对话场景中的蛛丝马迹判断出对方的情感&#xff0c;继而根据对话的主题等信息思考自身用什么情感进行回复&#xff0c;最后结合推理出的情感形成恰当的回复。受人类处理情感对话的启发&#xff0c;情感对话机器人需要完成以下几…

在新疆乌鲁木齐的汽车托运

在新疆乌鲁木齐要托运的宝! 看过来了 找汽车托运公司了 连夜吐血给你们整理了攻略!! ⬇️以下&#xff1a; 1 网上搜索 可以在搜索引擎或专业的货运平台上搜索相关的汽车托运公司信息。在网站上可以了解到公司的服务范围、托运价格、运输时效等信息&#xff0c;也可以参考其他车…

Ubuntu中安装搜狗输入法教程(详细图文教程)

习惯了使用搜狗输入法&#xff0c;这里总结了Ubuntu系统下安装搜狗输入法的详细教程&#xff0c;每个步骤都很详细&#xff0c;耐心安装。 搜狗输入法是一款功能强大、使用方便的输入法&#xff0c;能够有效提升用户在Ubuntu系统中的输入体验。 目录 一、下载搜狗安装包1.1 搜…

SpringCloud原理-OpenFeign篇(四、请求原理)

文章目录 前言正文一、书接上回&#xff0c;从代理对象入手二、ReflectiveFeign.FeignInvocationHandler#invoke()三、SynchronousMethodHandler#invoke(...) 的实现原理3.1 invoke(...)源码3.2 executeAndDecode(...) 执行请求并解码 四、如何更换client 的实现 附录附1&#…

【精选】框架初探篇之——MyBatis的CRUD及配置文件

MyBatis增删改查 MyBatis新增 新增用户 持久层接口添加方法 void add(User user);映射文件添加标签 <insert id"add" parameterType"com.mybatis.pojo.User">insert into user(username,sex,address) values(# {username},# {sex},# {address}) <…

NX二次开发UF_CURVE_ask_joined_parms 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_joined_parms Defined in: uf_curve.h int UF_CURVE_ask_joined_parms(tag_t joined_curve_feature, UF_STRING_p_t uf_curve_string, int * creation_method, double …

Git仓库瘦身大作战:133M 到 4M 的实战

开局两张图 瘦身前瘦身后 目录 开局两张图前言下载 BFG克隆代码Git 仓库瘦身清理存储库储存库 GC推送仓库 Git 瘦身验证结语开源项目 前言 在进行项目开发的过程中&#xff0c;代码仓库的体积可能会逐渐增大&#xff0c;特别是在版本控制系统中保留了大量的历史提交记录和不必…

apple macbook M系列芯片安装 openJDK17

文章目录 1. 查找openjdk版本2. 安装openjdk3. 多jdk之间的切换 在这里我们使用 brew 命令查找并安装。 1. 查找openjdk版本 执行&#xff1a;brew search openjdk&#xff0c;注意&#xff1a;执行命令后&#xff0c;如果得到的结果中没有红框内容&#xff0c;则需要更新一下…

使用STM32+SPI Flash模拟U盘

试验目的&#xff1a;使用STM32F103C8T6 SPI Flash&#xff08;WSQ16&#xff09;实现模拟U盘的功能 SPI Flash读写说明&#xff1a; Step1 设置SPI1 用于读取SPI Flash&#xff1b; Step2&#xff1a;设置SPI Flash 的使能信号 Step3&#xff1a;使能USB通信 Step4&#xf…