• JZ22 链表中倒数最后k个结点


    题目:
    链表中倒数最后k个结点

    题解:链表无法逆序访问,也不能通过下标直接访问。故不能逆序遍历链表得到最后k个结点。

    解法一:遍历链表用ArrayList存储每一个节点,然后通过下标访问。
    当k大于链表长度或者k=0时返回null
    倒数第k个节点就是正序list.size()-k个节点。

     public ListNode FindKthToTail (ListNode pHead, int k) {
            List<ListNode> list = new ArrayList<>();
            while(pHead!=null){
                list.add(pHead);
                pHead=pHead.next;
            }
            if(k>list.size()||k==0){
                return null;
            }
            return list.get(list.size()-k);
        }
    

    复杂度分析:
    时间复杂度:O(n),总共遍历n个链表元素
    空间复杂度:O(n),list存储n个链表元素

    解法二:快慢双指针
    双指针指的是在遍历的过程中,使用两个指针遍历(特殊情况甚至可以多个),两个指针或是同方向访问两个链表、或是同方向访问一个链表(快慢指针)、或是相反方向扫描(对撞指针)。

    构造两个快慢指针,使其之间的距离一直为k,那么当快指针到达链表尾部的时候,慢指针刚好处于倒数第k个位置。

    public ListNode FindKthToTail (ListNode pHead, int k) {
            ListNode fast = pHead;
            ListNode slow = pHead;
            while (k > 0 && fast != null) {
                fast = fast.next;
                k--;
            }
            if (k > 0) {
                return null;
            }
            while (fast != null) {
                slow = slow.next;
                fast = fast.next;
            }
            return slow;
        }
    

    第一个while循环,正常情况下k=0,fast!=null,但是如果k大于链表的长度,则fast=null,k>0,属于异常数据,所以在while循环外做了一次k是否大于0的判断。

    复杂度分析:
    时间复杂度:O(n),总共遍历2n-k个链表元素,O(n)+O(n-k)
    空间复杂度:O(1),没有借助额外的内存空间

    解法三:先获取到链表长度n,倒数第k个节点就是正向第n-k个节点。解法三与解法一思想有点类似,都是将倒数第k个节点转换成正向第n-k个节点。区别在于解法一用到了额外的存储空间,解法三多遍历了n-k个节点

    public ListNode FindKthToTail (ListNode pHead, int k) {
            int size = 0;
            ListNode node = pHead;
            while (node != null) {
                size++;
                node = node.next;
            }
            if (k > size) {
                return null;
            }
            int num = size - k;
            while (num > 0) {
                pHead = pHead.next;
                num--;
            }
            return pHead;
        }
    

    复杂度分析:
    时间复杂度:O(n),总共遍历2n-k个链表元素,O(n)+O(n-k)
    空间复杂度:O(1),没有借助额外的内存空间

    总结:
    涉及数据结构:链表
    涉及算法:快慢双指针

  • 相关阅读:
    PostgreSQL的学习心得和知识总结(一百一十)|深入理解PostgreSQL数据库 日志格式jsonlog 的使用场景和实现原理
    【无人机】基于蚁群算法的无人机航路规划研究附matlab代码
    Apache Hudi Timeline:支持 ACID 事务的基础
    python socketserver模块开启ssl双向认证
    使用一个命令使您的 Python 代码更优雅、更易读或更现代
    【无标题】数字孪生技术即神器而又象征着未来的点滴
    我的毕业设计思路
    Linux命令总结详细
    《痞子衡嵌入式半月刊》 第 65 期
    Qt-qrencode开发-生成、显示二维码
  • 原文地址:https://blog.csdn.net/qq_44300280/article/details/127122501