面試題22:鏈表中倒數第k個節點
題目要求:
求鏈表中倒數第k個節點。鏈表的尾節點定義為倒數第1個節點。
解題思路:
如果先求鏈表的長度,計算后再從頭遍歷,雖然時間復雜度是o(n),但需要兩遍掃描。更好的方式是使用兩個距離為k的指針向右移動,這種方式只需掃描一遍。
chapter3主要考察細節,這道題也不例外。需要注意鏈表是否為空,鏈表長度是否達到k,k是否是個正數。
package structure;
/**
* Created by ryder on 2017/6/13.
*/
public class ListNode<T> {
public T val;
public ListNode<T> next;
public ListNode(T val){
this.val = val;
this.next = null;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ret.append("[");
for(ListNode cur = this;;cur=cur.next){
if(cur==null){
ret.deleteCharAt(ret.lastIndexOf(" "));
ret.deleteCharAt(ret.lastIndexOf(","));
break;
}
ret.append(cur.val);
ret.append(", ");
}
ret.append("]");
return ret.toString();
}
}
package chapter3;
import structure.ListNode;
/**
* Created by ryder on 2017/7/14.
* 鏈表中倒數第k個節點
*/
public class P134_KthNodeFromEnd {
public static ListNode<Integer> findKthToTail(ListNode<Integer> head,int k){
if(head==null||k<=0)
return null;
ListNode<Integer> slow=head,fast=head;
for(int i=0;i<k;i++){
//i==k-1,第三個測試例通不過
if(fast.next!=null || i==k-1)
fast = fast.next;
else
return null;
}
while(fast!=null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
public static void main(String[] args){
ListNode<Integer> head = new ListNode<>(1);
head.next= new ListNode<>(2);
head.next.next = new ListNode<>(3);
System.out.println(findKthToTail(head,1).val);
System.out.println(findKthToTail(head,2).val);
System.out.println(findKthToTail(head,3).val);
System.out.println(findKthToTail(head,4));
}
}
運行結果
3
2
1
null