面试题22. 链表中倒数第k个节点

1:题目描述

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

 

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2:题目分析

思路1:常规思路

  1. 首先遍历链表长度为n。
  2. 再从头遍历链表n-k步,找到倒数第k个节点即可!

思路2:由于第一种方法,要通过两次遍历链表,浪费一定时间,所以我们可以通过双指针的方式来遍历链表一次即能定位到倒数第k个节点。

  1. 定义former和latter指针初始化为head位置。
  2. 先将former移动k步。latter保持不变。
  3. 然后再将former和latter指针一起向后移动,直到former到达尾部后的null,这是latter即为倒数第k位链表
  4. return latter

思路3:如何才能避免多次遍历?我们可以时钟保存当前node前的k-1个node,当指针到达尾部的时,则直接再保存的数组里的节点,直接输出即可,用空间换速度。

3:代码示例

思路2:

    public ListNode getKthFromEndDoublePointer(ListNode head, int k) {
        //定义前后双指针
        ListNode former = head;
        ListNode latter = head;

        //former指针先移动k步
        for(int i=0;i<k;i++){
            former = former.next;
        }

        //双指针同时移动,指代former值为null
        while(true){
            if(former == null){
                break;
            }
            former = former.next;
            latter = latter.next;
        }

        return latter;
    }

思路3:

    public ListNode getKthFromEnd(ListNode head, int k) {
        //创建缓存数组
        ListNode[] arrayNode = new ListNode[k];
        int i = 0;
        ListNode curNode = head;
        while(true){
            if(curNode == null){
                break;
            }
            //按照当前位置,存入对应数组中
            arrayNode[i%k] = curNode;
            curNode = curNode.next;
            i++;
        }
        //找到目标节点
        ListNode result = arrayNode[(i-k)%k];
        return result;
    }

 

posted @ 2020-03-13 12:19  大朱123  阅读(121)  评论(0编辑  收藏  举报