劍指offer面試題15:鏈表中倒數第K個節點

題目:輸入一個鏈表,輸出該鏈表的倒數第K個節點。爲了符合大多數人的習慣,本題從1開始計數,即鏈表尾節點是倒數第一個節點。 
解題思路: 解法一:通常狀況下,單向鏈表沒法從後一個節點獲取到它前面的節點,能夠經過兩次遍歷,第一次遍歷獲取鏈表中節點的個數,第二次遍歷找到鏈表中第n-k+1個節點,就是鏈表的倒數第k個節點。
可是這種方法效率低,能夠使用一次遍歷獲得倒數第K個節點 解法二:一次遍歷獲得倒數第K個節點。維護兩個指針,第一個指針從鏈表頭結點向前走k-1步,第二個節點指向頭結點,從第K步開始,若是走在前面的節點有下一個節點,那兩個節點一塊兒向前走,
直到第一個節點走到尾節點,此時第二個節點指向倒數第K個節點
程序健壯性考慮: 1.輸入鏈表爲null 2.輸入k爲0或小於0 3.鏈表節點總數小於k

 1 package Solution;
 2 
 3 public class No15FindKthNodeFromEnd {
 4 
 5     public static class ListNode {
 6         int data;
 7         ListNode next;
 8 
 9         public ListNode(int value, ListNode next) {
10             this.data = value;
11             this.next = next;
12         }
13     }
14 
15     public static ListNode findKthNodeFromEnd(ListNode head, int k) {
16         if (head == null)
17             throw new RuntimeException("待查找的鏈表不能爲空");
18         if (k <= 0)
19             throw new RuntimeException("輸入的位置數字不合法");
20         ListNode ahead = head;
21         ListNode behind = head;
22         // 第一個指針先指向K-1,並檢驗鏈表中節點個數是否大於k
23         int count = 1;
24         for (int i = 0; i < k - 1; i++) {
25             if (ahead.next != null) {
26                 ahead = ahead.next;
27                 count++;
28             } else
29                 throw new RuntimeException("鏈表節點個數:" + count + " 小於輸入K的個數:" + k);
30         }
31         while (ahead.next != null) {
32             ahead = ahead.next;
33             behind = behind.next;
34         }
35         return behind;
36     }
37 
38     public static void main(String[] args) {
39         ListNode node1 = new ListNode(4, null);
40         ListNode node2 = new ListNode(3, node1);
41         ListNode node3 = new ListNode(2, node2);
42         ListNode head = new ListNode(1, node3);
43         ListNode find = findKthNodeFromEnd(head, 3);
44         System.out.println("找到的節點位" + find.data);
45         ListNode find2 = findKthNodeFromEnd(head, 5);
46         System.out.println("找到的節點位" + find2.data);
47     }
48 }
相關文章
相關標籤/搜索