牛客網在線編程專題《劍指offer-面試題15》鏈表中倒數第k個節點

題目鏈接:

https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

題目描述:

解題思路:

(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);
	}

}