LeetCode题目:链表中倒数第k个节点

题目描述:

输入一个链表,输出该链表中倒数第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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

要找到倒数第k个节点,首先先到的想法就是先确定链表的长度n,再重头开始前进n-k+1步。但是确定长度n要先遍历一次链表,到后面找到倒数第k个节点,还要遍历一次链表,这就需要遍历两次了。
有一个想法:倒数第k个节点距离尾节点的距离就是k-1,设置两个指针,一个前指针,一个后指针,前指针先往前走,走了k-1步之后,前后指针就同时往前走,直到前指针到达尾部,这样后指针就在前面距离尾部k-1的位置了,返回后指针的节点就可以了。
这个中间还要防止输入节点为空,或者倒数第0个节点的情况,这两种情况下都是无意义的,返回null;再有就是输入的k,比链表的长度n还大,所以是找不到这个节点的,处理这个情况需要再遍历的时候加入一个判断条件,如果还没到达k,就已经到了链表的尾部,就直接返回null。

代码(Java):

public class doingmyself {
	public static void main(String[] args) {
		int[] nums = {1,2,3,4,5};
		List<ListNode> list = new ArrayList<ListNode>();
		for(int num:nums) {
			ListNode node = new ListNode(num);
			list.add(node);
		}
		for(int i = 0;i<list.size()-1;i++) {
			list.get(i).next = list.get(i+1);
		}
		ListNode head = list.get(0);
		ListNode ans = getKthFromEnd(head,2);
		System.out.println();
	}
	
	public static ListNode getKthFromEnd(ListNode head, int k) {
		if(head == null || k == 0) { //如果输入的节点是空的,或者k等于零,倒数第0个没意义,直接返回null
			return null;
		}
		
		//设置前后两个节点,利用倒数第k个节点与尾节点有k-1的距离,采用一次遍历找出倒数第k个节点
		ListNode dummy = new ListNode(0);
		dummy.next = head;
		ListNode pFront = dummy;  //两个指针都从head节点的前节点开始出发
		ListNode pBehind = dummy;
		
		for(int i = 0;i<k-1;i++) {  //尾节点和倒数第k个节点有k-1的距离,先让前节点前进k-1的距离
			if(pFront.next != null) {  //条件判断,预防k比输入节点的长度还大,这种情况下直接返回null
				pFront = pFront.next;
			}else {
				return null;
			}
		}
		while(pFront.next != null) { //前节点前进了k-1之后,前后节点一起向前出发,直到前节点到达了最后一个节点,后节点就到达了倒数第k个节点
			if(pFront.next != null) { //条件判断,预防k比输入节点的长度还大,这种情况下直接返回null
				pFront = pFront.next;
				pBehind = pBehind.next;
			}else {
				return null;
			}
		}
		
		return pBehind; //返回找到的倒数第k个节点
	}
}

class ListNode{
	int val;
	ListNode next;
	ListNode(int x){
		val = x;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值