剑指offer面试题15 链表中倒数第k个结点

考察点

链表

知识点

双指针遍历链表

题目

分析
这道题目需要倒数第k个结点,假设链表中总共n个结点,倒数第k个结点就是正数第n-k+1个结点,这是个数学小tips,如果不能识别出这层关系的话可以通过归纳法的方式找出数字的规律,这种方法需要我们遍历2遍链表,第一遍算出n的值,第二步找到第n-k+1个结点。有没有只遍历一次链表的方法呢?肯定有,链表的考点一般会考到双指针,所以思维一定要往双指针上靠,通过第一种方法能够看到倒数第k个结点就是正数第n-k+1个结点,最后那个结点是正数第n-1个结点,俩个结点相差n-1-(n-k+1) = k-2个步,按照这个思路,如果我们先让其中一个指针从头结点开始往后走k-2步,然后让第二个指针从头结点开始和第一个指针同时往后遍历,当快指针遍历到最后一个结点的时候,慢指针所指的结点就是我们要寻找的结点

public class LinkNode {
	int val;
	LinkNode next;

	public LinkNode(int data) {
		this.val = data;
		this.next = null;
	}
}
public class LinkList {
	LinkNode head;
	public LinkList() {
		this.head = null;
	}
	//找到倒数第k个元素
	public LinkNode findTailKth(int k) {
		if (this.head == null || k <= 0) {
			return null;
		}
		LinkNode pFirst = this.head;
		LinkNode pSecond = this.head;
		for(int i = 0;i < k - 1;i++) {
			if (pFirst.next == null) {
				return null;
			}
			pFirst = pFirst.next;
		}
		while(pFirst.next != null) {
			pSecond = pSecond.next;
			pFirst = pFirst.next;
		}
		return pSecond;
	}
	//添加元素
	public void addNode(int data) {
		LinkNode node = new LinkNode(data);
		if (this.head == null) {
			this.head = node;
		} else {
			LinkNode cur = this.head;
			while(cur.next != null) {
				cur = cur.next;
			}
			cur.next = node;
		}
	}
	//清空
	public void clear() {
		this.head = null;
	}
}
public class Fifteen {
	public static void main(String[] args) {
		LinkList linkList = new LinkList();
		linkList.addNode(1);
		linkList.addNode(2);
		linkList.addNode(3);
		linkList.addNode(4);
		LinkNode val = linkList.findTailKth(1);
		if (val != null) {
			System.out.println("val " + val.val);
		}
		LinkNode vala = linkList.findTailKth(2);
		if (vala != null) {
			System.out.println("vala " + vala.val);
		}
		LinkNode valb = linkList.findTailKth(22);
		if (valb != null) {
			System.out.println("valb " + valb.val);
		}
		LinkNode valc = linkList.findTailKth(-22);
		if (valc != null) {
			System.out.println("valc" + valc.val);
		}
		linkList.clear();
		LinkNode vald = linkList.findTailKth(2);
		if (vald != null) {
			System.out.println("vald" + vald.val);
		}
	}
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值