1.题目
剑指 Offer 22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
2.自我思路及实现
1.栈
将节点压入栈中,弹出第k个节点即可
时间:N+k,遍历所有节点+k次循环
空间:N,使用栈
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null)
return head;
Stack<ListNode> stack = new Stack<>();
while(head != null)
{
stack.push(head);
head = head.next;
}
for(int i = 1; i < k; i++)
{
stack.pop();
}
return stack.pop();
}
}
2.双端队列
维护一个大小为k的双端队列,有元素进入队列则将队列头元素出队,直到无新的元素,返回此时队列头元素即可
时间:N,所有元素入队列
空间:k
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null)
return head;
Deque<ListNode> deque = new LinkedList<>();
for(int i = 1; i <= k; i++)
{
deque.offerLast(head);
head = head.next;
}
while(head != null)
{
deque.offerLast(head);
deque.pollFirst();
head = head.next;
}
return deque.pollFirst();
}
}
3.动态数组
将节点加入数组,返回倒数第K个
时间:N
空间:N
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null)
return head;
ArrayList<ListNode> arr = new ArrayList<>();
while(head != null)
{
arr.add(head);
head = head.next;
}
return arr.get(arr.size() - k);
}
}
3.总结思路及实现
4.双指针(效率较高)
一个指针先指到K -1位,然后两个指针同时移动,当前指针指到尾端时,后指针就是倒数第K个
时间:N
空间:1
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null)
return head;
ListNode i = head;
ListNode j = head;
while(k-- > 0)
{
i = i.next;
}
while(i != null)
{
i = i.next;
j = j.next;
}
return j;
}
}
5.递归(效率较高)
归的时候计数,返回第k次时对应的节点
方法功能:返回链表中倒数第K个节点
终止条件: 链表为空
递归方法:当递归往下传递到最底端的时候,就会触底反弹往回走,在往回走的过程中记录下走过的节点,当达到k的时候,说明到达的那个节点就是倒数第k个节点,直接返回即可,如果没有达到k,就返回空
class Solution {
int count = 1;
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null)
return head;
ListNode node = getKthFromEnd(head.next, k);
if(count++ == k)
return head;
return node;
}
}