牛客网在线编程专题《剑指offer-面试题15》链表中倒数第k个节点
题目链接:
题目描述:
解题思路:
(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);
}
}