題目鏈接:
題目描述:
解題思路:
(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); } }