学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

2024-09-09 04:28

本文主要是介绍学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 删除排序链表中的重复元素
      • 我的思路
        • 解法一:循环
        • 解法二:递归
      • 网上思路
    • 删除排序链表中的重复元素 II
      • 我的思路
      • 网上思路
    • 总结

删除排序链表中的重复元素

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

图一
在这里插入图片描述

图二
在这里插入图片描述

示例 1:(图一)
输入:head = [1,1,2]
输出:[1,2]示例 2:(图二)
输入:head = [1,1,2,3,3]
输出:[1,2,3]

我的思路
两个思路,一个是循环,一个是递归
网上思路
双指针

我的思路

解法一:循环
var deleteDuplicates = function(head) {let current = head;while (current && current.next) {if (current.val === current.next.val) {current.next = current.next.next; } else {current = current.next;}}return head;
};

讲解

  1. 初始化指针:创建一个指针 current 指向链表的头节点。
  2. 遍历链表:遍历链表直到 current.next 为空。
  3. 检查重复:如果当前节点 current 的值与下一个节点 current.next 的值相同,则跳过下一个节点,即将 current.next 设置为 current.next.next
  4. 继续遍历:如果当前节点 current 的值与下一个节点 current.next 的值不同,则将 current 指针移动到下一个节点。
  5. 返回结果:遍历完成后返回链表的头节点。
解法二:递归
var deleteDuplicates = function (head) {if (head === null || head.next === null) return head;if (head.next.val === head.val) {head.next = head.next.next;return deleteDuplicates(head);} else {head.next = deleteDuplicates(head.next);return head;}
};

讲解

  1. 如果链表为空(head === null) 或只有一个节点 (head.next === null),则返回头节点,因为没有重复节点需要删除。
  2. 如果当前节点的值与下一个节点的值相同**(head.next.val === head.val)**,则说明存在重复节点。
  3. 通过 head.next = head.next.next,我们将当前节点的 next 指向下一个节点的下一个节点,从而跳过了重复节点。
  4. 然后递归调用 deleteDuplicates(head),继续检查当前节点**(head)**的下一个节点。
  5. 如果当前节点的值与下一个节点的值不相同,说明没有重复节点。
  6. 递归调用 deleteDuplicates(head.next) 处理下一个节点,并将返回的结果赋值给 head.next,以确保链表的结构保持正确。

网上思路

var deleteDuplicates = function (head) {if (!head) return head;let prev = head;let current = head.next;while (current) {if (current.val === prev.val) {prev.next = current.next;} else {prev = current;}current = current.next;}return head;
};

讲解

  1. 初始化指针:
    prev 指向链表的头节点。
    current 指向头节点的下一个节点。
  2. 遍历链表:
    使用 while (current) 来遍历整个链表
  3. 检查重复:
    如果 current.val 和 prev.val 相同,说明存在重复。
    prev.next = current.next:通过调整 prevnext 指针,跳过重复的节点。
  4. 移动指针:
    如果当前节点和前一个节点的值不同,则移动 prev 指针到当前节点。
    无论是否有重复,current 指针始终向前移动。

删除排序链表中的重复元素 II

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

图三
在这里插入图片描述

图四
在这里插入图片描述

示例 1:(图三)
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]示例 2:(图四)
输入:head = [1,1,1,2,3]
输出:[2,3]

我的思路
双指针
网上思路
递归

我的思路

var deleteDuplicates = function (head) {let dummy = new ListNode(0, head);let prev = dummy;let curr = head;while (curr && curr.next) {if (curr.val === curr.next.val) {while (curr.next && curr.val === curr.next.val) {curr = curr.next;}prev.next = curr.next;} else {prev = prev.next;}curr = curr.next;}return dummy.next;
};

讲解

  1. 创建哑节点:为了方便处理头节点可能被删除的情况,我们可以在链表前面添加一个哑节点。
  2. 初始化指针:创建一个指针 prev 指向哑节点,创建一个指针 curr 指向链表的头节点。
  3. 遍历链表:遍历链表直到 curr 到达末尾。
  4. 检查重复:如果当前节点 curr 的值与下一个节点 curr.next 的值相同,则继续向前遍历直到找到一个不同的节点。
  5. 连接不同节点:一旦找到不同的节点,将 prev.next 设置为这个不同的节点。
  6. 更新指针:如果没有重复节点,则将 prevcurr 都移动到下一个节点。
  7. 返回结果:遍历完成后返回哑节点的下一个节点作为新的头节点。

网上思路

var deleteDuplicates = function (head) {if (!head || !head.next) return headif (head.val === head.next.val) {while (head.next && head.next.val === head.val) head.next = head.next.nextreturn deleteDuplicates(head.next)} else {head.next = deleteDuplicates(head.next)}return head
};

讲解

  1. 基本情况检查:
    if (!head || !head.next) return head:如果链表为空**(head 为 null)或者只有一个节点(head.next 为 null)**,则直接返回 head。这是递归的基本情况,表示链表已经处理完成。
  2. 检查当前节点与下一个节点的值:
    if (head.val === head.next.val):检查当前节点的值是否与下一个节点的值相同。如果相同,说明存在重复节点。
  3. 跳过重复节点:
    while (head.next && head.next.val === head.val) head.next = head.next.next:使用 while 循环,继续跳过所有与当前节点值相同的节点, 直到找到一个不同的节点或到达链表末尾。
  4. 递归调用:
    return deleteDuplicates(head.next):在跳过所有重复节点后,递归调用 deleteDuplicates 处理下一个节点,并返回处理后的链表。
  5. 处理不同的节点:
    else { head.next = deleteDuplicates(head.next) }:如果当前节点的值与下一个节点的值不同,递归调用 deleteDuplicates 处理下一个节点,并将返回的结果赋值给 head.next
  6. 返回处理后的头节点:
    return head:最后,返回处理后的链表头节点。

总结

链表的题目写了这么多天,好像都可以用递归来解题,今天尝试了一下,还是不错的,后面可以再多尝试尝试。

这篇关于学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150154

相关文章

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Python中lambda排序的六种方法

《Python中lambda排序的六种方法》本文主要介绍了Python中使用lambda函数进行排序的六种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1.对单个变量进行排序2. 对多个变量进行排序3. 降序排列4. 单独降序1.对单个变量进行排序

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

SpringBoot项目删除Bean或者不加载Bean的问题解决

《SpringBoot项目删除Bean或者不加载Bean的问题解决》文章介绍了在SpringBoot项目中如何使用@ComponentScan注解和自定义过滤器实现不加载某些Bean的方法,本文通过实... 使用@ComponentScan注解中的@ComponentScan.Filter标记不加载。@C

MySQL中删除重复数据SQL的三种写法

《MySQL中删除重复数据SQL的三种写法》:本文主要介绍MySQL中删除重复数据SQL的三种写法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录方法一:使用 left join + 子查询删除重复数据(推荐)方法二:创建临时表(需分多步执行,逻辑清晰,但会

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6