被火车撞了都不能忘记的几道题(你会了吗?)

2023-11-20

目录

一.删除有序链表中的重复元素I

二.删除有序链表重复元素II

三.环形单链表中插入一个元素

四.单链表翻转II

五.奇偶链表


一.删除有序链表中的重复元素I

1.对应牛客网链接:

删除有序链表中重复的元素-I_牛客题霸_牛客网 (nowcoder.com)

2.题目描述:

 3.解题思路

1.定义一个cur和next指针一开始cur指向头,next指针指向头的下一个

2.边遍历边比较 cur->val == next->val若相等,则将 cur 就指向 next 的下一个节点,否则继续遍历,直至遍历完整个链表。

下面以1->2->3->3->4为例:

由于 cur 指向的节点的值(1)不等于 next 指向的节点的值(2),两个指针右移

不相等继续后移

相等,cur 指向 next 的下一节点(相当于删除链表中的重复元素 3),next 指针右移

直到next为空

4.对应代码

class Solution {
  public:
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here

        if (head == nullptr || head->next == nullptr) {
            return head;
        }

        ListNode* cur = head;
        ListNode* next = head->next;
        while (next) {
            if (cur->val == next->val) { //重复
                while (next && next->val == next->val) {
                    ListNode* next = cur->next; //保存下一个节点
                    delete cur;
                    cur = next;
                }
                cur->next = next;
            } else {
                //指针一起移动
                cur = next;
                next = next->next;
            }
        }
        return head;
    }
};

递归版本:

class Solution {
  public:
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        if (!head || !head->next) {
            return head;
        }
        ListNode* next = head->next;
        if (head->val != next->val) {
            head->next = deleteDuplicates(head->next);
            return head;
        } else {
            while (next && next->val == head->val) {
                head->next = next->next;
                delete next;
                next = head->next;
            }
            head->next = deleteDuplicates(head->next);
            return head;
        }
    }
};

二.删除有序链表重复元素II

1.对应牛客网链接:

删除有序链表中重复的元素-II_牛客题霸_牛客网 (nowcoder.com)

2.题目描述:

 3.解题思路

1.定义一个三个指针变量:last 、prev、cur一开始分别指针空、头节点和头节点的下一个

2.迭代变量如果prev的值和cur的值相等那么一直移动cur直到cur的值和prev不相等。如果prev的值和cur不相等则三个指针一起移动。直到cur为空

下面我们以1->3->3->4->4->5为例:

初始状态:

 发现prev和cur的值不相等三个指针一起移动

 此时prev和cur的值一样我们进行删除:

删除完成之后我们发现prev和cur的值又相等了继续进行删除

 

直到cur走到空结束循环将头节点返回即可

注意:(如果一开始就是头删需要进行特判改变头节点) 

4.对应代码

class Solution {
  public:
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        if (head == nullptr || head->next == nullptr) {
            return head;
        }
        ListNode* prev = head;
        ListNode* cur = head->next;
        ListNode* last = nullptr;
        while (cur) {
            if (cur->val == prev->val) {
                while (cur && cur->val == prev->val) {//进行删除
                    ListNode* next = cur->next;
                    delete cur;
                    cur = next;
                }
                delete prev;
                prev = cur;
                cur = cur ? cur->next : nullptr;
                if (last == nullptr) {//特判头删的情况
                    head = prev;
                } else {
                    last->next = prev;

                }
            } else {//三个指针迭代走
                last = prev;
                prev = cur;
                cur = cur->next;
            }
        }
        return head;
    }
};

递归版本:


class Solution {
  public:
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        if (head == nullptr || head->next == nullptr) {
            return head;
        }

        if (head->val != head->next->val) {
            head->next = deleteDuplicates(head->next);
            return head;
        } else {
            //说明相等
            int val = head->val;
            while (val == head->val) {
                ListNode* next = head->next;
                delete head;
                head = next;
                if (head == nullptr)
                    return nullptr;

            }
            return deleteDuplicates(head);
        }
    }

};

三.环形单链表中插入一个元素

1.对应letecode链接:

剑指 Offer II 029. 排序的循环链表 - 力扣(LeetCode)

2.题目描述:

3.解题思路:

 插入情况一:链表为空创建一个节点让自己指向自己

插入情况二:单链表只有一个节点或单链表中所有节点的值都相等

插入情况三:找到一个插入位置使其前节点值比Insertval小,后节点值比其Insertval大

情况四:当插入节点为最小值或者最大值

4.对应代码:


class Solution {
  public:
    Node* insert(Node* head, int insertVal) {
        if (head == NULL) {
            Node* newNode = new Node(insertVal);
            newNode->next = newNode;
            return newNode;
        }
        Node* cur = head;
        while (1) {
            if (cur->next ==
                    head) { //说明可能只有一个节点或者全是一种值的节点
                break;
            } else if (cur->val <= insertVal && cur->next->val >= insertVal) {
                break;
            } else if (cur->val > cur->next->val && (insertVal >= cur->val ||
                       insertVal <= cur->next->val)) {
                break;
            }
            cur = cur->next;
        }
        cur->next = new Node(insertVal, cur->next);
        return head;

    }
};

四.单链表翻转II

1.对应牛客网链接

链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com)

2.题目描述:

3.解题思路:

1.指向 left左边元素的指针 pre ,它表示未翻转的链表,需要把当前要翻转的链表结点放到 pre 之后。

cur 指向当前要翻转的链表结点。

nxt 指向 cur.next ,表示下一个要被翻转的链表结点。

tail 指向已经翻转的链表的结尾,用它来把已翻转的链表和剩余链表进行拼接

 

 4.对应代码:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode*temp=nullptr;
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        // write code here
        if(m==1)
        {
            return ReversN(head, n);
        }
        ListNode*node=reverseBetween(head->next, m-1, n-1);
        head->next=node;
        return head;
    }
    ListNode*ReversN(ListNode*head,int n)
    {
        if(n==1)
        {
            temp=head->next;//保存后面的节点
            return head;
        }
        ListNode*node=ReversN(head->next,n-1);
        //开始翻转
        head->next->next=head;
        head->next=temp;
        return node;
        
    }
};

递归版本:

1.如果m ==1,就相当于反转链表的前n元素。
2.如果m != 1我们把 head的索引视为1,那么我们是想从第m个元素开始反转,如果扎head.next的索引视为1,那相对于head.next,反转的区间3.应该是从第m-1个元素始的,以此类推,递归拼接后续已反转的链表。
对于每次反转,如果n等于1,相当于只颠倒第一个节点,如果不是,则进入后续节点问题),将后续反转的内容接到前面即可。
对应代码
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode*temp=nullptr;
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        // write code here
        if(m==1)
        {
            return ReversN(head, n);
        }
        ListNode*node=reverseBetween(head->next, m-1, n-1);
        head->next=node;
        return head;
    }
    ListNode*ReversN(ListNode*head,int n)
    {
        if(n==1)
        {
            temp=head->next;//保存后面的节点
            return head;
        }
        ListNode*node=ReversN(head->next,n-1);
        //开始翻转
        head->next->next=head;
        head->next=temp;
        return node;
        
    }
};

五.奇偶链表

1.对应letecode链接:

328. 奇偶链表 - 力扣(LeetCode)

2.题目描述:

 3.解题思路:

1.根据节点编号的奇偶性,我们可以将奇数节点和偶数节点分离成奇数链表和偶数链表,然后将偶数链表连接在奇数链表之后,合并后的链表即为结果链表。

2、从前往后遍历整个链表,遍历时维护四个指针:奇数链表头结点,奇数链表尾节点,偶数链表头结点,偶数链表尾节点,遍历时将位置编号是奇数的节点插在奇数链表尾节点后面,将位置编号是偶数的节点插在偶数链表尾节点后面。

4.对应代码:

class Solution {
  public:
    ListNode* oddEvenList(ListNode* head) {
        if (head == nullptr) {
            return nullptr;
        }
        ListNode* oddList = head;
        ListNode* EeveList = head->next;
        ListNode* oddcur = oddList;
        ListNode* evercur = EeveList;
        ListNode* cur = head;
        while (evercur && evercur->next) {//链表长度有可能是奇数或者是偶数
            oddcur->next = evercur->next;
            oddcur = oddcur->next;
            evercur->next = oddcur->next;
            evercur = evercur->next;
        }
        oddcur->next = EeveList;//链接
        return head;

    }
};

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

被火车撞了都不能忘记的几道题(你会了吗?) 的相关文章

随机推荐

  • 协同过滤算法代码

    此算法主要用来推荐的 找出ui uj两个用户同时打过分的课程集合 function getPSet uid ujd select 课程编号 from 评分 where 用户编号 ui and 课程编号 in select 课程编号 from
  • linux使用date命令获取系统时间

    转载自Linux系统date命令的参数及获取时间戳的方法 date指令相关用法示例 date 用法 date OPTION FORMAT date u utc universal MMDDhhmm CC YY ss 直接输入date dat
  • 微信小程序开发之——用户登录-登录流程(1)

    一 概述 新建微信小程序自带用户登录简化 小程序登录流程时序 二 新建微信小程序自带用户登录简化 新建的微信小程序默认有用户登录功能 将多余功能去除后 简化如下 2 1 index wxml
  • 文心一言续写太监小说《名侦探世界的巫师》

    名侦探世界的巫师 是我的童年回忆 总是想着续写一下 但是又没有时间和文笔 文心一言出了 由于目前大模型貌似可以联网 可以尝试搞一波 目录 文章1 前六个故事还能看 后面就是在重复 故事2 辣眼睛 毁童年 非请勿看 故事3 流水账 故事4 其
  • JDK介绍

    JDK JRE和JVM之间的关系 JVM是运行环境 JRE是含运行环境和相关的类库 跟node环境是一个意思 JDK目录介绍 目录名称 说明 bin 该路径下存放了JDK的各种工具命令 javac和java就放在这个目录 conf 该路径下
  • C++学习笔记(十六):对vector进行更多的操作——泛型算法

    先强调一下 这里的泛型算法实际不光光是对vector的操作 对于 顺序容器 均可以 但是什么是顺序容器 我们都知道 容器就是一些特定类型对象的集合 而顺序容器为程序员提供了控制元素存储和访问的能力 这种容器的一个显著的特征 就是容器中元素的
  • ES6.x版本单机三节点配置discovery.zen.ping.unicast.hosts 错误

    问题 在同一个机子利用不同端口搭建3个ES节点 单节点正常运行 集群间无法联通 找不到主节点 表现 cluster uuid 一直没有注册成功 curl 0 0 0 0 29200 name es 01 cluster name es te
  • 浏览器地址栏输入url以后发生了什么

    在浏览器输入url后会发生的过程 1 DNS对域名进行解析 2 建立TCP连接 三次握手 3 发送HTTP请求 4 服务器处理请求 5 返回响应结果 6 关闭TCP连接 四次挥手 7 浏览器解析HTML 8 浏览器布局渲染 1 浏览器对输入
  • 华为OD机试 - 需要打开多少监控器(Java & JS & Python)

    题目描述 某长方形停车场 每个车位上方都有对应监控器 当且仅当在当前车位或者前后左右四个方向任意一个车位范围停车时 监控器才需要打开 给出某一时刻停车场的停车分布 请统计最少需要打开多少个监控器 输入描述 第一行输入m n表示长宽 满足1
  • 按照 C++ 11 标准,数组,指针,传递问题!

    一 一维数组 静态 int array 100 定义了数组array 并未对数组进行初始化 静态 int array 100 1 2 定义并初始化了数组array 动态 int array new int 100 delete array
  • Java 日历的制作 心得 写给自己

    之前已经跟着老师做过一次这个日历 但是时间一久便又拿出来自己再复习一遍 果然不出所料 已经做不出来了 而且因为在学习的时候使用的是Myeclipse 其中话中操作是由软件自己操作的 每写出一句代码软件也会自动提示哪里有问题 半傻瓜式的操作果
  • HTML5的多个video标签:截取视频源的封面图poster,监听视频播放状态的功能;

    在日常项目中 html5的video标签还是比较常用到的 开发过程中 我们都会使用到 通过监听video标签的播放 暂停 停止等等来使用 我们是否也会遇到过 有些浏览器在显示这标签 兼容不太友好 video标签的封面是一层黑色的 ok 那么
  • git-基本操作-1

    1安装 window上安装git 官网直接下载 下载完成后需要在git bash命令行中输入 git config global user name yourname git config global user email yourema
  • 非常详细的小程序搜索历史功能

    前言 我们在进行一些项目开发时 很有可能会涉及到在搜索框中搜索某一个词条 从而进行相应的检索 在这里就会出现一个优化功能 我们在搜索后的某一个词条 我希望能够显示在历史记录中 这样一个小的tip 可以给用户带来更高的使用体验 历史记录并不会
  • goland环境配置

    goland modules环境配置 下载和安装goland 环境配置 配置环境变量GOPATH 配置go modules GOPROXY代理的系统变量 工程目录中新建三个工作目录 goland中启用go modules 新建一个go程序
  • 浅谈图数据库

    本文主要讨论图数据库背后的设计思路 原理还有一些适用的场景 以及在生产环境中使用图数据库的具体案例 从社交网络谈起 下面这张图是一个社交网络场景 每个用户可以发微博 分享微博或评论他人的微博 这些都是最基本的增删改查 也是大多数研发人员对数
  • 【电子技术】什么是LFSR?

    目录 0 前言 1 数学基础 1 1 逻辑异或 1 2 模2乘法 和 模2除法 2 线性反馈移位寄存器LFSR 3 抽头和特征多项式 4 阶线性反馈移位寄存器实例 0 前言 线性反馈移位寄存器 Linear Feedback Shift R
  • mysql jdbc 实现读写分离

    这种方式直接在代码级别实现了mysql 读写分离 很简单 只需要改一下配置文件 就搞定了 是不是很嗨 jdbc driverClassName com mysql jdbc ReplicationDriver jdbc url jdbc m
  • Windows10安装Markdown安装教程(超级详细)

    markdown其实就是我们平常写博客的地方 下面我来详细介绍它的安装教程 首先到官网去安装 markdown 点击download 我反正点击download后它自动就下载了 然后下载好后是安装包 双击 然后一直next 最后它会跳出来
  • 被火车撞了都不能忘记的几道题(你会了吗?)

    目录 一 删除有序链表中的重复元素I 二 删除有序链表重复元素II 三 环形单链表中插入一个元素 四 单链表翻转II 五 奇偶链表 一 删除有序链表中的重复元素I 1 对应牛客网链接 删除有序链表中重复的元素 I 牛客题霸 牛客网 nowc