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;
            };


  虚拟头节点:链表头地址可能发生改变
相关文章
|
人工智能 自动驾驶 算法
智能时代的伦理困境:AI决策的道德边界
在人工智能技术飞速发展的今天,我们面临着前所未有的伦理挑战。本文探讨了AI决策中的道德边界问题,分析了技术发展与人类价值观之间的冲突,并提出了建立AI伦理框架的必要性和可能路径。通过深入剖析具体案例,揭示了AI技术在医疗、司法等领域的应用中所引发的道德争议,强调了在追求技术进步的同时,必须审慎考虑其对社会伦理的影响,确保科技发展服务于人类的福祉而非成为新的困扰源。
|
自然语言处理 关系型数据库 MySQL
MySQL索引之全文索引(FULLTEXT)
MySQL索引之全文索引(FULLTEXT) MySQL创建全文索引 使用索引时数据库性能优化的必备技能之一。
8481 0
MySQL索引之全文索引(FULLTEXT)
|
5月前
|
人工智能 资源调度 安全
意图共鸣科技发布《认知智能白皮书》:AI认知架构(CA)与认知操作系统(COS)——如何解决大模型“能做事但不懂事”的结构性缺陷
《认知智能白皮书》由东莞市意图共鸣科技有限公司创始人陈金桥于2026年5月发布。直指大模型“能力强但无分寸”的结构性缺失,首创“认知架构(CA)+认知操作系统(COS)”双层框架,为AI构建类神经系统的感知、判断与调度能力,推动从“裸算力”迈向可信赖的认知智能。
447 5
|
定位技术
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
1723 0
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
|
人工智能 自然语言处理 搜索推荐
阿里巴巴首批企业级Agent来了!
阿里巴巴旗下瓴羊推出首批企业级Agent应用,包括“超级客服专家”和“超级电销专家”,基于多年电商经验与AI技术,显著提升客服与销售效率。通过自动化处理退换货、售后补发、线索筛选等任务,企业效率提升超60%,助力实现“人+Agent”协同新模式。
2104 0
|
10月前
|
存储 自然语言处理 Java
为什么 Elasticsearch 搜索这么快?深入理解倒排索引与分词器原理
Elasticsearch 搜索快的秘诀在于倒排索引与分词器。倒排索引通过“词项→文档ID”映射,避免全表扫描;分词器则负责文本的切分与归一化处理,提升检索效率。本文图解剖析其核心原理,助你掌握ES高性能搜索的底层逻辑。(238字)
|
存储 机器学习/深度学习 人工智能
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
749 3
|
人工智能 安全 网络安全
借助 SentinelOne 全新的风险保障计划变革网络安全保险市场
2025年信息技术系统故障凸显技术风险即商业风险。SentinelOne与多家顶尖保险公司合作推出“风险保障计划”,通过Singularity™平台结合AI技术,助力企业提前阻止攻击、减少财务损失。该计划提供高达100万美元的数据泄露响应保障,并支持安全数据共享以优化保单激励。SentinelOne连续三年获评Gartner领导者,其解决方案为中小企业和中型市场企业提供全面网络安全防护,确保业务安心无忧。
472 1
|
数据采集 物联网 API
理解异步编程:从日常场景到代码逻辑
异步编程是现代高并发应用开发的核心技术之一。通过Python的asyncio库,利用事件循环机制与协程,可高效处理I/O密集型任务。相比同步模式,异步能显著减少资源闲置,如在Web请求、文件读写时“变废为宝”。文章从同步与异步对比、协程原理、事件循环机制,到实战案例(爬虫性能测试)及常见误区解决,全面解析异步编程。其适用于高并发I/O场景,但不推荐用于CPU密集型任务。掌握异步编程,如同拥有精巧工具,在合适场景下大幅提升系统性能。
928 0