高频链表算法

news2024/11/20 15:18:18

1.从尾到头打印链表值

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)

思路

(1)如果使用数组来保存反转之后的链表数据,这样只需要使用到队列或栈的知识,关键是unshif和push,reverse函数

(2)如果不使用数组,可以考虑使用双指针的办法来解决,主要将头结点的next改为null,然后接下来的每个值都改一下next值

   //从尾到头打印链表值
    //数组法
    var resver = function (head) {
      let arr = [];
      while (head !== null) {
        arr.unshift(head);
        head = head.next;
      }
      return arr;
    };
    //双指针法
    var resver=function(head){
      let temp=null;//保存中间值而已
      let cut=head;//代表要改变他的next的值
      let pre=null;//代表cut要指向的next值
      while(cut!==null){//1!==null   2!==null
        temp=cut.next;//temp=1.next:2   temp=2.next:3
        cut.next=pre;//cut.next:1.next=null  cut.next:2.next=1
        pre=cut;//pre=1  pre=2
        cut=temp;//cut=2  cut=3
      }
      return pre;
    }

2.两两交换链表中的节点

 

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

 

 //两两交换链表中的节点
    var head = [1, 2, 3, 4, 3];
    var resver = function (head) {
      if (head == null || head.next == null) return head;
      let pm = new LinkNode(0, head);
      // rm是指针,pm是虚拟头结点
      let rm = pm;
      while (rm.next && rm.next.next) {
        //1 2,3 4,3.next=null退出循环
        // temp代表要交换的第一个数值
        let temp = rm.next; //temp=1  temp=3
        // cut代表要交换的第二个数值
        let cut = rm.next.next; //cut=2  cut=4
        //将两个数值交换的前一个数值的next改为第二个数值
        rm.next = cut; //rm.next=2   rm.next:1.next=4
        //将第一个数值的next改为第二个数值的下一个数值
        temp.next = cut.next; //temp.next:1.next=2.next:3    3.next=4.next:null
        // 将第二个数值的next改为第一个数值
        cut.next = temp; //cut.next:2.next=1   4.next=3
        // 这里的rm代表要交换的两个数值的前一个数值
        rm = temp; //rm=1 rm=3
      }
      return pm.next;
    };

3.删除链表的倒数第N个节点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

思路

双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。

 // 删除链表的倒数第n个结点
    var dele = function (head, n) {
      let rm = new LinkNode(0, head);
      let slow = rm;
      let fast = rm;
      while (n--) {
        fast = fast.next;
      }
      while (fast.next !== null) {
        slow = slow.next;
        fast = fast.next;
      }
      // 这里注意不要写成slow.next=fast;因为可能fast不止只有一个值
      slow.next = slow.next.next;
      return rm.next;
    };

 4.合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的

//合并两个递增的链表
    var sortArr = function (arrA, arrB) {
      let lot = new LinkNode(0, arrA);
      let p1 = arrA;
      let p2 = arrB;
      let temp = lot;
      if (!p1) {
        return p2;
      }
      if (!p2) {
        return p1;
      }
      while (p1 && p2) {
        if (p1.val < p2.val) {
          temp.next = p1;
          p1 = p1.next;
        } else {
          temp.next = p2;
          p2 = p2.next;
        }
        temp = temp.next;
      }
      temp.next = p1 ? p1 : p2;

      return lot.next;
    };

5.链表相交

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交:

 

思路

先找到两个链表的长度len1,len2 让长一点的链表先走len2-len1步,使得两个链表距离链表尾部的长度相同; 两个链表一起走,并比较节点是否相同,相同即为公共节点,判断是否相同是需要值相同,并下一个节点也相同

var getIntersectionNode = function(headA, headB) {
    if(!headA || !headB){return null;}
    let len1 = getLength(headA);
    let len2 = getLength(headB);
    let long, short, gap;
    //判断哪个链表长度更长
    if(len1 > len2){
        long = headA;
        short = headB;
        gap = len1 - len2;// 求长度差
    }else{
        long = headB;
        short = headA;
        gap = len2 - len1;// 求长度差
    }
    //让长链表先走gap步
    while(gap-- > 0){
        long = long.next; // 让curA和curB在同一起点上(末尾位置对齐)
    }
    //两个链表一起走,判断第一个公共节点
    while(long){
        if(long === short){// 遍历curA 和 curB,遇到相同则直接返回
            return long;
        }
        long = long.next;
        short = short.next;
    }
    return null;
};
function getLength(head){
    let cur = head;
    let len = 0;
    while(cur){
        len++;
        cur = cur.next;
    }
    return len;
}

6.移除链表元素

可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。

删除链表中等于给定值 val 的所有节点。

输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]

 //移除链表元素
    var dele=function(val,head){
      let headnode=new LinkNode(0,head);
let cut=headnode;
      while( cut.next){
      
        if( cut.next.val==val){
          cut.next=cut.next.next;

        }else{
          cut=cut.next;
        }
      }
      return headnode.next;
    }

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

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

相关文章

【vue2】vuex基础与五大配置项

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;vuex基础认识、state、getters、mutations actions、modules使用 目录(文末原素材) 一、…

【JavaEE初阶】第九节.多线程 (基础篇)定时器(案例三)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 一、定时器概述、 二、定时器的实现 2.1 Java标准库 定时器的使用 2.2 自己模拟实现一个定时器 2.3 对自己实现的定时器的进一步优化 2.3.1 为何需要再进行优化 2…

CMOS图像传感器——了解光圈

在之前有提到传感器英寸,也提到了曝光三要素之一的ISO,这里主要说明另外一个曝光三要素——光圈。在本文中,我们将介绍光圈及其工作原理。 一、什么是光圈 光圈可以定义为镜头中的开口,光线通过该开口进入相机。类比眼睛是的工作原理,就容易理解了:当人在明亮和黑暗的环…

【链表之单链表】

前言&#xff1a;链表是什么&#xff1f; 链表的操作 1.单链表的结构 2.头文件的包含 3.动态申请一个节点 4.单链表打印 5.单链表尾插 6.单链表头插 7.单链表尾删 8.单链表头删 9.单链表查找 10.单链表在pos位置之后插入x 11.单链表在pos位置之前插入x 12. 单链表…

【数据挖掘】基于粒子群算法优化支持向量机PSO-SVM对葡萄酒数据集进行分类

1.粒子群算法的概念 PSO是粒子群优化算法&#xff08;Particle Swarm Optimization&#xff09;的英文缩写&#xff0c;是一种基于种群的随机优化技术&#xff0c;由Eberhart和Kennedy于1995年提出。粒子群算法是模仿昆虫、兽群、鸟群和鱼群等的群集行为&#xff0c;这些群体按…

中国电子学会2021年03月份青少年软件编程Scratch图形化等级考试试卷三级真题(含答案)

2021-03Scratch三级真题 分数&#xff1a;100题数&#xff1a;38 一、单选题(共25题&#xff0c;每题2分&#xff0c;共50分) 1.在《采矿》游戏中&#xff0c;当角色捡到黄金时财富值加1分&#xff0c;捡到钻石时财富值加2分&#xff0c;下面哪个程序实现这个功能&#xff1…

【软件测试】资深测试总结的测试必备8点,堪称测试人的好莱坞大片......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试8板斧。测试8板…

Task8:Excel的数据可视化

目录一 条形图二 条件单元格格式三 迷你图四 练习题一 条形图 【例子】直观的展示销售额之间的差别 方法&#xff1a;【开始】–>【条件格式】–>【数据条】 【只想显示条形图&#xff0c;不想显示金额】 1.条形图区域—>条件格式—>管理规则 2.选择设置的规则&a…

单应性Homography梳理,概念解释,传统方法,深度学习方法

Homography 这篇博客比较清晰准确的介绍了关于刚性变换&#xff0c;仿射变换&#xff0c;透视投影变换的理解 单应性变换 的 条件和表示 用 [无镜头畸变] 的相机从不同位置拍摄 [同一平面物体] 的图像之间存在单应性&#xff0c;可以用 [透视变换] 表示 。 opencv单应性变换求…

Active Directory计算机备份和恢复

在Active Directory&#xff08;AD&#xff09;环境中&#xff0c;用户通过域中的计算机认证他们自身。从AD中删除这些计算机账户时&#xff0c;系统也会自动从域中删除它们。于是&#xff0c;用户不能再通过些计算机登录网络。为允许用户访问域资源&#xff0c;必须恢复这些已…

聚集千百个企业管理系统的API资产,打造API资产全生命周期一站式集成体验

API——接口&#xff0c;作为软件世界中的连接服务和传输数据的重要管道&#xff0c;已经成为数字时代的新型基础设施&#xff0c;是各领域驱动数字变革的重要力量之一。传统企业集成主要采用点对点或ESB集成方式&#xff0c;基于全新API战略中台的API新型集成方式通过解耦系统…

SpringBoot跨域请求解决方案详细分析

跨域的定义 跨域是指不同域名之间的相互访问&#xff0c;这是由浏览器的同源策略决定的&#xff0c;是浏览器对JavaScript施加的安全措施&#xff0c;防止恶意文件破坏。同源策略&#xff1a;同源策略是一种约定&#xff0c;它是浏览器最核心的也是最基本的安全策略&#xff0…

【数据产品】缓存设计

背景&#xff1a;为什么需要做缓存&#xff1f; 我所做的产品的指标设计越来越复杂&#xff0c;查询性能也随之下降。因此需要增加缓存层&#xff0c; 以提高接口查询效率。 哪些层需要做缓存&#xff1f; 随着指标系统的应用&#xff0c;该产品的查询逻辑也越来越简单&…

二分查找核心思路--单调性--极值

在最初的二分查找中&#xff0c;我们将一组数据按大小排序&#xff0c;然后根据arr[mid]与要查找的k的大小比较&#xff0c;从而每次去掉一半的数字&#xff0c;使时间复杂度简化为O&#xff08;logN&#xff09;。 排序本质上是让数据的单调性统一&#xff0c;变为单增或单减…

spring中的JSR-303统一校验

1.在前后端的传输参数的过程中数据在何处校验? 在前后端都需要进行校验,只是分工不同. 2.各个层的校验内容: 1.Controller层主要负责校验残水的合法性,包括: 必填的参数字段,数据格式的校验 2.Service层的业务校验是审核业务中的规则的相关内容,比如:课程已经审核通过所以提…

vue3 为何比 vue2 快

vue3 为何比 vue2 快 测试环境&#xff1a;https://vue-next-template-explorer.netlify.app/ 1、proxy 响应式 vue3 优缺点&#xff1a; 深度监听性能更好可监听 新增 / 删除 属性可监听数组变化Proxy 能规避 Object.defineProxy 的问题Proxy 无法兼容所有浏览器&#xff…

OAuth2介绍

目录 一、什么是OAuth2 二、OAuth2中的角色 三、认证流程 四、令牌的特点 五、OAuth2授权方式 授权码 隐藏方式 密码方式 凭证方式 一、什么是OAuth2.0 概念&#xff1a;第三方授权解决方案 OAuth2.0是目前使用非常广泛的授权机制&#xff0c;用于授权第三方应用获取…

[NRF52] mesh DFU

mesh DFU升级过程&#xff1a;完整流程&#xff1a;以前nRF SDK DFU的实现是通过nRF51 Dongle配合主机nRF connect工具&#xff0c;且借助Secure DFU的后台式更新速率较快&#xff08;见另一篇笔记&#xff09;&#xff0c;现在的nRF mesh DFU分角色&#xff0c;全都由DK充当&a…

什么是单体应用?什么是微服务?

Monolith&#xff08;单体应用&#xff09;&#xff0c; 也称之为单体系统或者是 单体架构 。就是一种把系统中所有的功能、模块、组件等耦合在一个应用中应用最终打成一个(war,jar)包使用一个容器(Tomcat)进行部署&#xff0c;通常一个应用享用一个数据库。 也就是将所有的代码…

Java版数据结构与算法笔记

文章目录一、数据结构与算法概述及题目1、数据结构和算法的关系2、线性结构与非线性结构Ⅰ-线性结构Ⅱ-非线性结构3、经典面试题Ⅰ-字符串匹配问题&#xff1a;Ⅱ-汉诺塔游戏Ⅲ-八皇后问题:Ⅳ-马踏棋盘算法4、几个实际编程中遇到的问题Ⅰ-字符串替换问题Ⅱ-一个五子棋程序Ⅲ-约…