Implement an algorithm to find the kth to last element of a singly linked list. Return the value of the element.
Note: This problem is slightly different from the original one in the book.
Example:
Input: 1->2->3->4->5 和 k = 2
Output: 4
Note:
k is always valid.
Solutions
Solution 1: Two Pointers
Thinking
The \(k\)-th node from the end is the \((n-k+1)\)-th from the front. A counting pass plus a second walk is correct; a single pass is enough.
If the fast pointer starts \(k\) steps ahead, it hits the end exactly when the slow pointer sits on the \(k\)-th from the end.
Both start at the head; fast advances \(k\) times, then they move together until fast is null, and slow.val is returned.
We define two pointers slow and fast, both initially pointing to the head node head. Then the fast pointer moves forward \(k\) steps first, and then the slow and fast pointers move forward together until the fast pointer points to the end of the list. At this point, the node pointed to by the slow pointer is the \(k\)-th node from the end of the list.
The time complexity is \(O(n)\), where \(n\) is the length of the list. The space complexity is \(O(1)\).
1 2 3 4 5 6 7 8 910111213141516
# Definition for singly-linked list.# class ListNode:# def __init__(self, x):# self.val = x# self.next = NoneclassSolution:defkthToLast(self,head:ListNode,k:int)->int:slow=fast=headfor_inrange(k):fast=fast.nextwhilefast:slow=slow.nextfast=fast.nextreturnslow.val
1 2 3 4 5 6 7 8 9101112131415161718192021
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */classSolution{publicintkthToLast(ListNodehead,intk){ListNodeslow=head,fast=head;while(k-->0){fast=fast.next;}while(fast!=null){slow=slow.next;fast=fast.next;}returnslow.val;}}
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funckthToLast(head*ListNode,kint)int{slow,fast:=head,headfor;k>0;k--{fast=fast.Next}forfast!=nil{slow=slow.Nextfast=fast.Next}returnslow.Val}