【牛客面试必刷TOP101】Day18.BM14 链表的奇偶重排和BM16 删除有序链表中重复的元素-II

作者简介:大家好,我是未央;

博客首页:************************************************************************************************************************************************************************************************************************************************************未央.303****************************************************************************************************************************************************************************************************************************************************************

系列专栏:牛客面试必刷TOP101****

每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!!!

文章目录

前言

一、链表的奇偶重排

题目描述

题目解析

二、删除有序链表中重复的元素-II

题目描述

题目解析

总结



前言

一、链表的奇偶重排

题目描述

描述:

给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。

注意:是节点的编号而非节点的数值。


数据范围:节点数量满足 0≤n≤10^5,节点中的值都满足 0≤val≤1000;

要求:空间复杂度 O(n),时间复杂度O(n)。


示例1:


示例2:


**备注:**链表长度不大于200000。每个数范围均在int内。


题目解析

解题思路:

题目主要信息:

  • 给定一个链表,将奇数位的节点依次连在前半部分,偶数位的节点依次连在后半部分;
  • 返回连接后的链表头;

方法:双指针(推荐使用)

思路:

如下图所示,第一个节点是奇数位,第二个节点是偶数,第二个节点后又是奇数位,因此可以断掉节点1和节点2之间的连接,指向节点2的后面即节点3,如红色箭头。

如果此时我们将第一个节点指向第三个节点,就可以得到那么第三个节点后为偶数节点,因此我们又可以断掉节点2到节点3之间的连接,指向节点3后一个节点即节点4,如蓝色箭头。那么我们再将第二个节点指向第四个节点,又回到刚刚到情况了。

代码:

java 复制代码
//odd连接even的后一个,即奇数位
odd.next = even.next; 
//odd进入后一个奇数位
odd = odd.next; 
//even连接后一个奇数的后一位,即偶数位
even.next = odd.next; 
//even进入后一个偶数位
even = even.next; 

这样我们就可以使用了两个同方向访问指针遍历解决这道题。


解题步骤:

  • step 1:判断空链表的情况,如果链表为空,不用重排。
  • step 2:使用双指针odd和even分别遍历奇数节点和偶数节点,并给偶数节点链表一个头。
  • step 3:上述过程,每次遍历两个节点,且even在后面,因此每轮循环用even检查后两个元素是否为NULL,如果不为再进入循环进行上述连接过程。
  • step 4:将偶数节点头接在奇数最后一个节点后,再返回头部。

图示过程解析:


代码编写:



二、删除有序链表中重复的元素-II

题目描述

描述:
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。


举例说明:

给出的链表为1→2→3→3→4→4→5, 返回1→2→5.
给出的链表为1→1→1→2→3, 返回2→3.


数据范围:链表长度 0≤n≤10000,链表中的值满足∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

进阶:空间复杂度 O(1),时间复杂度 O(n)


示例1:


示例2:



题目解析

解题思路:

题目的主要信息:

  • 在一个非降序的链表中,存在重复的节点,删除该链表中重复的节点
  • 重复的节点一个元素也不保留

方法:直接遍历比较删除(推荐使用)

思路:

这是一个升序链表,重复的节点都连在一起,我们就可以很轻易地比较到重复的节点,然后将所有的连续相同的节点都跳过,连接不相同的第一个节点。

代码:

java 复制代码
//遇到相邻两个节点值相同
if(cur.next.val == cur.next.next.val){ 
    int temp = cur.next.val;
    //将所有相同的都跳过
    while (cur.next != null && cur.next.val == temp) 
        cur.next = cur.next.next;
}

解题步骤:

  • step 1:给链表前加上表头,方便可能的话删除第一个节点。
  • step 2:遍历链表,每次比较相邻两个节点,如果遇到了两个相邻节点相同,则新开内循环将这一段所有的相同都遍历过去。
  • step 3:在step 2中这一连串相同的节点前的节点直接连上后续第一个不相同值的节点。
  • step 4:返回时去掉添加的表头。

图示过程解析:


代码编写:


总结

相关推荐
Ljubim.te27 分钟前
软件设计师——数据结构
数据结构·笔记
_GR1 小时前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
无限大.2 小时前
c语言实例
c语言·数据结构·算法
@haihi2 小时前
冒泡排序,插入排序,快速排序,选择排序
数据结构·算法·排序算法
丢掉幻想准备斗争2 小时前
数据结构(栈和队列的实现)
数据结构
zengy53 小时前
Effective C++中文版学习记录(三)
数据结构·c++·学习·stl
&梧桐树夏6 小时前
【算法系列-链表】删除链表的倒数第N个结点
数据结构·算法·链表
QuantumStack6 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
wclass-zhengge7 小时前
数据结构篇(绪论)
java·数据结构·算法
Dylanioucn7 小时前
【分布式微服务云原生】探索Redis:数据结构的艺术与科学
数据结构·redis·分布式·缓存·中间件