剑指offer第二版-22.链表中倒数第k个节点

本系列导航:剑指offer(第二版)java实现导航帖

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

题目要求:
求链表中倒数第k个节点。链表的尾节点定义为倒数第1个节点。

解题思路:
如果先求链表的长度,计算后再从头遍历,虽然时间复杂度是o(n),但需要两遍扫描。更好的方式是使用两个距离为k的指针向右移动,这种方式只需扫描一遍。
chapter3主要考察细节,这道题也不例外。需要注意链表是否为空,链表长度是否达到k,k是否是个正数。

package structure;
/**
 * Created by ryder on 2017/6/13.
 */
public class ListNode<T> {
    public T val;
    public ListNode<T> next;
    public ListNode(T val){
        this.val = val;
        this.next = null;
    }
    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append("[");
        for(ListNode cur = this;;cur=cur.next){
            if(cur==null){
                ret.deleteCharAt(ret.lastIndexOf(" "));
                ret.deleteCharAt(ret.lastIndexOf(","));
                break;
            }
            ret.append(cur.val);
            ret.append(", ");
        }
        ret.append("]");
        return ret.toString();
    }
}
package chapter3;
import structure.ListNode;
/**
 * Created by ryder on 2017/7/14.
 * 链表中倒数第k个节点
 */
public class P134_KthNodeFromEnd {
    public static ListNode<Integer> findKthToTail(ListNode<Integer> head,int k){
        if(head==null||k<=0)
            return null;
        ListNode<Integer> slow=head,fast=head;
        for(int i=0;i<k;i++){
            //i==k-1,第三个测试例通不过
            if(fast.next!=null || i==k-1)
                fast = fast.next;
            else
                return null;
        }
        while(fast!=null){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
    public static void main(String[] args){
        ListNode<Integer> head = new ListNode<>(1);
        head.next= new ListNode<>(2);
        head.next.next = new ListNode<>(3);
        System.out.println(findKthToTail(head,1).val);
        System.out.println(findKthToTail(head,2).val);
        System.out.println(findKthToTail(head,3).val);
        System.out.println(findKthToTail(head,4));
    }
}

运行结果

3
2
1
null

推荐阅读更多精彩内容