走的最慢的人,只要他不丧失目标,也比漫无目的徘徊的人走得快。- 莱辛
输入一个链表,输出该链表中倒数第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
解题思路
一提到链表,好多题目都可以有几种相似的解法,但最好本着时间复杂度是O(N)的思路,即遍历链表一边即可,太多了,估计面试官不会认可。除了用空间换时间的想法,比如多开辟出一个数组来记录链表,还有但指针,大家都普遍认可的解法就是双指针法,也叫快慢指针法。本题为例:
生成两个指针从头节点开始,快指针先走k-1步,然后快慢指针同时向后,当快指针到达链表末尾的时候,慢指针正好处于第k个节点。代码也是相当的简单,讨论下时间复杂度,快指针走了O(N), 慢指针走了O(N-K),时间复杂度为 O(N), 空间复杂度为 O(1), 只有两个指针。
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode slow = head, fast = head;
for(int i =0; i< k -1; i++){
if(fast.next == null)
return null;
fast = fast.next;
}
while(fast.next != null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
相似的题型还有很多
876. 链表的中间结点 - 快指针是慢指针的两倍步长