The List

简介: The List

链表


链表判环(快慢指针)


[141.环形判环]: https://leetcode.cn/problems/linked-list-cycle/


解题思想:


  • 先判断head节点是否为空


  • 再利用快慢指针来判断,如果两个指针能够相等,则有环,否则快指针首选到尾节点后判断为null,则无环


(在javascript中,return null的结果为true,在c++中,return NULL的结果为false)


var hasCycle = function(head) {
    if(head === null) return false;
    let p1 = head; 
    let p2 = head.next;
    while(p2 && p2.next) {
        if(p1 === p2) return true;
        p1 = p1.next;
        p2 = p2.next.next;
    }
    return false;
};


[142.环形链表]: https://leetcode.cn/problems/linked-list-cycle-ii/


解题思想:


  • 如果链表的头节点或者第二个节点为null,则非循环链表


  • 然后进行快慢指针的相遇,如果快指针的q.next为null或者q.next.next为null则非循环链表


  • 如果快慢指针能够相遇,则说明是循环链表


  • 要找到循环的首节点,让慢指针重新从头节点开始走,让快指针恢复成慢指针的速度


  • 当他们相遇的时候就是循环链表的首节点


var detectCycle = function(head) {
      if(head === null || head.next === null) return null;
    let p = head, q = head;
      do {
        if(q.next === null || q.next.next === null) return null;
          p = p.next
        q = q.next.next
      } while(p != q)
    p = head;
      while(p !== q) {
        p = p.next;
          q = q.next;
    }
      return p;
};


[202.快乐数]: https://leetcode.cn/problems/happy-number/


解题思想:


  • 一个数组的每个位置平方和确定,可想象成链表形式,这个节点指向下一个节点


  • 先写出对应求平方和的方法,对一个数取余并平方,然后依此求下一位的平方


  • 然后将1看作链表中的null值即可按照链表判断有无环的方式进行判断是否为快乐数


function getNext(x) {
        let z = 0;
    while(x) {
            z += (x % 10) * (x % 10);
        x = parseInt(x / 10);
        }
      return z;
    }
  var isHappy = function(n) {
        if(n === 1) return true;
      let p = n, q = n;
        do {
          if(getNext(q) === 1 || getNext(getNext(q)) === 1) return true;
            p = getNext(p);
          q = getNext(getNext(q));
        } while(p !== q);
      return false;
    };


链表反转


[206.反转链表]: https://leetcode.cn/problems/reverse-linked-list/


解题思路:


  • 利用三个节点进行迭代反转


  • 如果链表为null,则直接返回即可


  • 利用三个节点反转,pre表示反转头,cur表示未反转头,下个带反转头


      var reverseList = function(head) {
          if(head === null) return head;
          let pre = null, cur = head, p = head.next;
          while(cur) {
              cur.next = pre;
              pre = cur;
              (cur = p) && (p = p.next);
          }
          return pre;
      };


2. 利用递归反转


  • 递归从尾节点进行反转


  • 当当前head为null或者head->next为null时表示为尾节点,返回head


  • 然后递归将head->next节点指向head节点


  • 然后将head节点指向null


         var reverseList = function(head) {
             if(head==null || head.next==null) return head
             let p = reverseList(head.next)
             head.next.next = head
             head.next = null
             return p
         };


[返回倒数第K个节点]: https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/


解题思路:


  • 利用前后指针


  • 先让前指针先走k-1步


  • 然后两个指针再一同走,如果前指针走到尾节点,后指针就在倒数第k个节点


    var kthToLast = function(head, k) {
          let p1 = head;
        let p2 = head;
          while(--k) {
            p1 = p1.next;
          }
        while(1) {
              if(p1.next === null) {
                  return p2.val;
              }
              p1 = p1.next;
              p2 = p2.next;
          }
      };


链表删除节点


[19.删除链表的倒数第N个结点]: https://leetcode.cn/problems/remove-nth-node-from-end-of-list/


解题思路:


  • 先创建一个虚拟头节点


  • 利用前后指针找到需要删除的节点的前一个节点


  • 将要删除的前一个节点指向被删除节点的后一个节点


  • 然后返回虚拟头节点的下一个节点


      var removeNthFromEnd = function(head, n) {
            let p = new ListNode(-1), res = p;p1 = p, p2 = p;
          p.next = head;
            while(n--) {
              p1 = p1.next;
            };
          while(1) {
                if(p1.next === null) {
                  p2.next = p2.next.next;
                    return res.next;
              }
                p1 = p1.next;
              p2 = p2.next;
            };
      };


[82.删除排序链表中重复元素]: https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/submissions/


解题思路:


  • 创建虚拟头节点


  • 循环判断当前结点的下一个结点和下下个结点不为空,进入循环判断


  • 如果当前结点的下一个结点值等于下下个结点值,将这个值临时存储


  • 当下一个结点存在,并且这个结点等于临时存储的值时,将当前结点指向下下个结点,即删除重复元素


  • 最后返回虚拟头节点的下一个结点


        var deleteDuplicates = function(head) {
              if(head === null) return head;
            let p = new ListNode(0, head), cur = p;
              while(cur.next && cur.next.next) {
                if(cur.next.val === cur.next.next.val) {
                      let temp = cur.next.val;
                      while(cur.next && cur.next.val === temp) {
                          cur.next = cur.next.next;
                      }
                  } else {
                      cur = cur.next;
                  }
              }
              return p.next;
          };


[83.删除排序链表中的重复元素]: https://leetcode.cn/problems/remove-duplicates-from-sorted-list/


解题思路:


  • 声明头节点,并判断当前结点的下一个结点是否存在


  • 再判断当前结点值是否等于下一结点值,如果相等,就将当前结点指向下下个结点,即删除重复结点


  • 最后返回头结点


            var deleteDuplicates = function(head) {
                let p = head;
                if(head === null) return null;
                while(p.next) {
                    if(p.val === p.next.val) {
                        p.next = p.next.next;
                    } else {
                        p = p.next;
                    }
                }
                return head;
            };


  虚拟头节点:链表头地址可能发生改变
相关文章
|
4月前
|
数据采集 存储 Web App开发
Python爬虫库性能与选型实战指南:从需求到落地的全链路解析
本文深入解析Python爬虫库的性能与选型策略,涵盖需求分析、技术评估与实战案例,助你构建高效稳定的数据采集系统。
434 0
|
JavaScript 前端开发
js+jquery实现贪吃蛇经典小游戏
本项目采用HTML、CSS、JavaScript和jQuery技术,无需游戏框架支持。通过下载项目文件至本地,双击index.html即可启动贪吃蛇游戏。游戏界面简洁,支持方向键控制蛇移动,空格键实现游戏暂停与恢复功能。
340 14
|
8月前
|
存储 自然语言处理 前端开发
2025年大模型发展脉络:深入分析与技术细节
本文深入剖析2025年大模型发展脉络,涵盖裸模型与手工指令工程、向量检索、文本处理与知识图谱构建、自动化提示生成、ReAct多步推理及AI Agent崛起六大模块。从技术细节到未来趋势,结合最新进展探讨核心算法、工具栈与挑战,强调模块化、自动化、多模态等关键方向,同时指出计算资源、数据质量和安全伦理等问题。适合关注大模型前沿动态的技术从业者与研究者。
2897 9
|
网络架构
YOLOv5改进 | 2023主干篇 | 利用RT-DETR特征提取网络PPHGNetV2改进YOLOv5(超级轻量化精度更高)
YOLOv5改进 | 2023主干篇 | 利用RT-DETR特征提取网络PPHGNetV2改进YOLOv5(超级轻量化精度更高)
754 0
|
9月前
|
弹性计算
关于阿里云无影云电脑的“核时”计算公式及40核时、80核时、160核时、320核时使用时间说明
核时是阿里云无影云电脑的CPU核心数与使用时间的乘积,用于衡量计算资源的消耗。例如,40核时可供4核8G配置的云电脑使用10小时,或8核16G配置使用5小时。若自带核时不足,可购买核时包,不同档位和有效期享有不同折扣。更多详情见阿里云官方文档及页面。 简而言之,核时帮助用户灵活管理计算资源,确保按需使用,避免浪费。
1823 19
|
安全 Linux Android开发
SELinux策略语法以及示例策略
本文来讲述 SELinux 策略常用的语法,然后解读一下 SELinux 这个项目中给出的示例策略
232 2
|
Java 容器
Stream 流常见基本操作
Stream 流常见基本操作
|
消息中间件 关系型数据库 MySQL
MySQL 到 Kafka 实时数据同步实操分享(1),字节面试官职级
MySQL 到 Kafka 实时数据同步实操分享(1),字节面试官职级
|
人工智能 运维 Serverless
【云故事探索】NO1:看森马服饰,在阿里云上如何用AI实现创新?
在数字化转型中,云计算成为企业创新的关键驱动力。森马服饰借助阿里云函数计算,应对新零售挑战,实现业务模式重塑和效率提升。面对AI技术落地的困难,如高成本、长决策周期和复杂运维,森马通过阿里云的Serverless解决方案,快速将AI融入核心业务,优化了从设计到营销的全链条流程。通过函数计算,森马降低了AI项目初期的硬件投入和运维难题,提升了设计师的工作效率,将设计时间从3天缩短到30秒,实现了服装设计和营销的智能化升级。
【云故事探索】NO1:看森马服饰,在阿里云上如何用AI实现创新?
|
存储 缓存 网络协议
2.8 基于DPDK的UDP用户态协议栈实现
2.8 基于DPDK的UDP用户态协议栈实现
718 0