zoukankan      html  css  js  c++  java
  • 6.查找单链表中的倒数第k个结点

     

    普通思路:先将整个链表从头到尾遍历一次,计算出链表的长度size,得到链表的长度之后,就好办了,直接输出第(size-k)个节点就可以了(注意链表为空,k

    为0,k为1,k大于链表中节点个数时的情况)。时间复杂度为O(n),大概思路如下:

    public int findLastNode(int index) {
            // index代表的是倒数第index的那个结点
            // 第一次遍历,得到链表的长度size
            if (head == null) {
                return -1;
            }
            int size = 0;
            current = head;
            while (current != null) {
                size++;
                current = current.next;
            }
            // 第二次遍历,输出倒数第index个结点的数据
            current = head;
            for (int i = 0; i < size - index; i++) {
                current = current.next;
            }
            return current.data;
    
        }

    如果面试官不允许你遍历链表的长度,该怎么做呢?接下来就是。

     改进思路:(这种思路在其他题目中也有应用)

     这里需要声明两个指针:即两个结点型的变量first和second,首先让first和second都指向第一个结点,然后让second结点往后挪k-1个位置,此时first和second就间隔了k-1个位置,然后整体向后移动这两个节点,直到second节点走到最后一个结点的时候,此时first节点所指向的位置就是倒数第k个节点的位置。时间复杂度为O(n)

     代码实现:(初版)

        public Node findLastNode(Node head, int index) {
            if (head == null) {
                return null;
            }
            Node first = head;
            Node second = head;
            // 让second结点往后挪index个位置
            for (int i = 0; i < index; i++) {
                second = second.next;
            }
            // 让first和second结点整体向后移动,直到second结点为Null
            while (second != null) {
                first = first.next;
                second = second.next;
            }
            // 当second结点为空的时候,此时first指向的结点就是我们要找的结点
            return first;
        }

    代码实现:(最终版)

    (考虑k大于链表中结点个数时的情况时,抛出异常)

    上面的代码中,看似已经实现了功能,其实还不够健壮: 

     要注意k等于0的情况;

    如果k大于链表中节点个数时,就会报空指针异常,所以这里需要做一下判断。 

    核心代码如下:

    public Node findLastNode(Node head, int k) {
            if (k == 0 || head == null) {
                return null;
            }
            Node first = head;
            Node second = head;
            // 让second结点往后挪k-1个位置
            for (int i = 0; i < k - 1; i++) {
                System.out.println("i的值是" + i);
                second = second.next;
                if (second == null) {
                    // 说明k的值已经大于链表的长度了 //throw new NullPointerException("链表的长度小于" + k); //我们自己抛出异常,给用户以提示
                    return null;
                }
            }
            // 让first和second结点整体向后移动,直到second走到最后一个结点
            while (second.next != null) {
                first = first.next;
                second = second.next;
            }
            // 当second结点走到最后一个节点的时候,此时first指向的结点就是我们要找的结点
            return first;
        }

     测试代码:

        public static void main(String[] args) {
            LinkList list = new LinkList();
            // 向LinkList中添加数据
            for (int i = 0; i < 10; i++) {
                list.add(i);
            }
            list.print(list.head);// 从head节点开始遍历输出
            System.out.print(list.getLength(list.head));
            System.out.print("
    ");
    //        System.out.print(list.findLastNode(10));
            System.out.print(list.findLastNode(list.head,7).getData());
            System.out.print("
    ");
            System.out.print(list.findMidNode(list.head).data);
            
        }
  • 相关阅读:
    不要进行过度设计,某一层存在真的有意义吗?是否可以更简单。
    化繁为简 定义权限
    Ajax加载子域跨站cookie丢失的问题.
    Exists 比Contains 慢非常多。
    ValidationExpression="http(s)?://([w-]+.)+[w-]+(/[w- ./?%&=]*)?" can not work
    全屏显示问题
    将System.Drawing.Bitmap转换为Direct2D.D2DBitmap
    《ASP.NET Core In Action》读书笔记系列,这是一个手把手的从零开始的教学系列目录
    《ASP.NET Core In Action》读书笔记系列五 ASP.NET Core 解决方案结构解析1
    《ASP.NET Core In Action》读书笔记系列四 创建ASP.NET Core 应用步骤及相应CLI命令
  • 原文地址:https://www.cnblogs.com/guweiwei/p/6846112.html
Copyright © 2011-2022 走看看