Kth to Last Element in Linked List #
Problem Statement #
Given the head of a singly linked list, return the kth to last element in the list. The kth to last element is the element that is k positions from the end of the list.
For example, if the list is 1 -> 2 -> 3 -> 4 -> 5 and k = 2, then the kth to last element is 4 (2nd from the end).
Note: k is 1-indexed, meaning k=1 refers to the last element, k=2 refers to the second-to-last element, etc.
Return null if k is larger than the length of the list.
Method Signature #
public static ListNode kthToLast(ListNode head, int k)
ListNode Definition #
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
Examples #
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: ListNode with value 4
Explanation: The 2nd to last element is 4
List: 1 -> 2 -> 3 -> 4 -> 5
↑
k=2 from end
Example 2:
Input: head = [1,2], k = 1
Output: ListNode with value 2
Explanation: The 1st to last element (last element) is 2
List: 1 -> 2
↑
k=1 from end
Example 3:
Input: head = [1], k = 1
Output: ListNode with value 1
Explanation: Single element list, k=1 returns the only element
Example 4:
Input: head = [1,2,3], k = 5
Output: null
Explanation: k=5 is larger than list length (3), so return null
Test Your Solution #
public class KthToLastTest {
public static void main(String[] args) {
// Helper method to create linked list
ListNode createList(int[] values) {
if (values.length == 0) return null;
ListNode head = new ListNode(values[0]);
ListNode current = head;
for (int i = 1; i < values.length; i++) {
current.next = new ListNode(values[i]);
current = current.next;
}
return head;
}
// Test case 1: [1,2,3,4,5], k=2
ListNode test1 = createList(new int[]{1, 2, 3, 4, 5});
ListNode result1 = kthToLast(test1, 2);
System.out.println("Test 1: " + (result1 != null ? result1.val : "null")); // Expected: 4
// Test case 2: [1,2], k=1
ListNode test2 = createList(new int[]{1, 2});
ListNode result2 = kthToLast(test2, 1);
System.out.println("Test 2: " + (result2 != null ? result2.val : "null")); // Expected: 2
// Test case 3: [1], k=1
ListNode test3 = createList(new int[]{1});
ListNode result3 = kthToLast(test3, 1);
System.out.println("Test 3: " + (result3 != null ? result3.val : "null")); // Expected: 1
// Test case 4: [1,2,3], k=5
ListNode test4 = createList(new int[]{1, 2, 3});
ListNode result4 = kthToLast(test4, 5);
System.out.println("Test 4: " + (result4 != null ? result4.val : "null")); // Expected: null
// Test case 5: empty list
ListNode test5 = null;
ListNode result5 = kthToLast(test5, 1);
System.out.println("Test 5: " + (result5 != null ? result5.val : "null")); // Expected: null
// Test case 6: [1,2,3,4,5,6], k=6
ListNode test6 = createList(new int[]{1, 2, 3, 4, 5, 6});
ListNode result6 = kthToLast(test6, 6);
System.out.println("Test 6: " + (result6 != null ? result6.val : "null")); // Expected: 1
}
// Your implementation goes here
public static ListNode kthToLast(ListNode head, int k) {
// TODO: Implement kth to last element finder
return null;
}
}
Solution
Extension Challenges #
- Kth from beginning: Find kth element from the start (simpler)
- Multiple k values: Find kth to last for multiple k values efficiently
- Doubly linked list: How would this change with backward pointers?
- Remove kth to last: Remove the kth to last element instead of returning it
- Circular linked list: Handle lists where last node points back to head
Real-World Applications #
- Undo functionality: Access recent actions (k steps back)
- Buffer management: Maintain sliding window of recent data
- Game development: Track player positions relative to end of path
- Text editors: Navigate to previous positions in document history
- Network protocols: Access recent packets in communication buffer