一.双指针法
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
//如果pHead为空,也没有倒数结点的这个说法
if(pHead == null) {
return null;
}
//用count来计算链表的长度
int count = 0;
//一个指针hum指向pHead
ListNode hum = pHead;
//遍历链表,得到链表的长度
while (hum != null) {
count++;
hum = hum.next;
}
//判断k的合法性,如果k<0或者k>链表的长度,那么倒数k个结点不成立
if (k < 0 || k > count) {
return null;
}
/**
* 如果k等于1且pHead.next为自身,那么倒数第一个结点就是他自己
*/
if (k == 1 && pHead.next == pHead) {
return pHead;
}
//定义两个指针,一个fast先走,一个slow后走,相差的距离刚好为k
ListNode fast = pHead;
ListNode slow = pHead;
//cur已经走到了倒数第k个节点的前一个节点
while (k != 0) {
k--;
/**
* 进入while循环需要判断fast是否已经为空了,
* 如果fast不等于空,走完while循环刚好走了k步
* 如果fast在这里为空了,说明k不合法,直接返回null
*/
if (fast != null) {
fast = fast.next;
}
}
/**
* fast已经走了k步了,slow同时再跟fast一起走
* fast为空的时候,slow的位置就是倒数的第k个结点
*/
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
//返回倒数第k个结点
return slow;
}
}
二.遍历思路
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
//如果pHead为空,返回null
if (pHead == null) {
return null;
}
//假设只有一个头结点且k刚好为1,那么说明倒数第一个结点就是pHead
if (k == 1 && pHead.next == pHead) {
return pHead;
}
//计数器为count用来计算链表的长度
int count = 0;
//定义一个指针cur指向pHead
ListNode cur = pHead;
//cur不为空的时候,cur指向cur.next
while (cur != null) {
count++;
cur = cur.next;
}
//验证k的合法性,如果k < 0或者k > count,找不到倒数的结点,直接返回null
if (k < 0 || k > count) {
return null;
}
/**
* 此时cur在链表的最后一个结点的下一个位置,cur这时候为空
* cur这时候再次指向头结点
*/
cur = pHead;
//刚好遍历count - k步,for循环结束的时候,cur指向的就是倒数第k个结点
for (int i = 0; i < count - k; i++) {
cur = cur.next;
/**
* 对于cur的合法性,如果出现cur指向为空,那么说明k就不合法,
* 根本也不会进入for循环
*/
}
//返回cur指向的结点
return cur;
}
三.反转链表法
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if (pHead == null) {
return pHead;
}
if (pHead.next == null && k == 1) {
return pHead;
}
int count = 0;
ListNode dummy = new ListNode(0);
dummy.next = pHead;
ListNode pre = dummy;
ListNode cur = pHead;
while (cur != null) {
count++;
cur = cur.next;
}
if (k < 0 || k > count || k == 0) {
return null;
}
cur = reverseList(pHead);
ListNode temp = cur;
//pre的指向就是第k个位置
while (k != 0) {
pre = cur;
cur = cur.next;
k--;
}
pre.next = null;
return reverseList(temp);
}
private static ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode cur = reverseList(head.next);
head.next.next = head;
head.next = null;
return cur;
}
}