题目链接:
题目描述:
解题思路:
(1)方法一:两次遍历链表
统计出链表中总共有多少个元素,然后找到第K个元素的位置,最后从链表的头部开始遍历到第k个元素的位置。
已经AC的代码:
public class findKthNode { class ListNode{ int val; ListNode next = null; public ListNode(int data) { this.val = data; } } public ListNode head; public void createLinkedList(int data) { if(head == null) { head = new ListNode(data); }else { ListNode node = new ListNode(data); node.next = head; head = node; } } public ListNode FindKthToTail(ListNode head,int k) { int count = 1; ListNode node = head; if(head == null) { return null; } while(node.next != null) { count++; node = node.next; } if(k > count) { return null; } node = head; for(int i=0; i<count-k; i++) { node = node.next; } return node; } public static void main(String[] args) { findKthNode list = new findKthNode(); for(int i=0; i<10; i++) { list.createLinkedList(i); } System.out.println(list.FindKthToTail(list.head, 10).val); } }
上面方法的缺点:
对于上面的方法,我们需要遍历链表两次,第一次统计出链表中节点的个数,第二次就能找到倒数第k个节点。但是当我们把这个思路解释给面试官之后,他会告诉我们他期待的解法只需要遍历链表一次。
(2)方法二:遍历一次链表
思路:
数据结构:单链表
算法:双指针
注意:代码的鲁棒性
已经AC的代码:
public class findKthNode { class ListNode{ int val; ListNode next = null; public ListNode(int data) { this.val = data; } } public ListNode head; public void createLinkedList(int data) { if(head == null) { head = new ListNode(data); }else { ListNode node = new ListNode(data); node.next = head; head = node; } } public ListNode FindKthToTail(ListNode head,int k) { if(head == null || k == 0) { return null; } ListNode p1 = head; ListNode p2 = null; for(int i=0; i<k-1; i++) { if(p1.next != null) { p1 = p1.next; }else { return null; } } p2 = head; while(p1.next!=null) { p1 = p1.next; p2 = p2.next; } return p2; } public static void main(String[] args) { findKthNode list = new findKthNode(); for(int i=0; i<10; i++) { list.createLinkedList(i); } System.out.println(list.FindKthToTail(list.head, 10).val); } }