**1. Ideas**

Suppose K is 2. According to the picture below, we can see that the Kth node from the bottom is 45.

The premise to be noted is that K cannot be negative or 0 and cannot exceed the number of nodes in the linked list, because it is necessary to ensure that K is within the range of the linked list to find K and then return this node. If this node cannot be found, it is impossible to return it.

Only after traversing all the nodes can it be possible to find the Kth node from the bottom, so it is definitely necessary to use a loop to traverse one node by one.

Then it is to judge whether the current node is the target node, if it is, jump out of the loop and return to this node; if not, then continue to find the next node until the linked list is completely traversed.

The next thing to realize is the end condition of the loop, that is, how to judge whether the current node is the target node.

You can first define two pointers, fast and slow, both point to the position of the head node at the beginning, but let fast take K-1 steps first.

Which node will be pointed to depends on K. If K is a negative number or 0, or exceeds the number of nodes in the linked list, the

position pointed to by fast is definitely illegal.

When K is 0, fast will go to the position of 0-1, which is obviously illegal at this time.

When K is -1, fast will go to the position of -1-1, which is still obviously illegal at this time.

When the value of K exceeds the number of nodes in the linked list, fast will eventually go beyond the linked list.

The above three illegal situations obviously cannot be used by me.

Therefore, at the very beginning of the code, it must first determine whether the current K is legal, and if it is legal, then go to the next step;

if not, return a null directly to indicate that the current value of K is problematic.

After fast walks K-1 steps, let the two nodes walk step by step. Since fast walks first, it will definitely walk more than slow. When the next node of fast is empty, then slow points to the Kth node from the bottom. At this point the loop is over, just return to slow after jumping out.

When the value of K is 1, fast takes K-1 steps, that is, does not move a step, and the two pointers start to move together at the position of the head node.

When the next node of fast is empty, it can be seen that slow points to exactly the last 1 (value of K) node.

This idea is not affected by odd and even nodes, and this method is applicable regardless of whether the linked list nodes are odd or even.

When fast completes K-1 steps, it will always take one more step than slow, so when the next node of fast is empty, slow points to the previous node of fast, which is the second last node (the value of K).

**2. Detailed process**

1. Firstly, judge whether the value of K is legal. If not, return a null directly.

```
//k位置不合法
if (k <= 0 || this.head == null) {
return null;
}
```

2. Define two pointers, one called **fast** and one called **slow** , and let them both point to the head node.

```
//定义一个fast和slow指向head
ListNode fast = this.head;
ListNode slow = this.head;
```

3. Let fast take K -1 steps first.

```
while (k - 1 != 0) {
fast = fast.next;
if (fast == null) {
return null;
}
k--;
}
```

Assuming that the value of K at this time is 2, fast will take one step first. If the current value of K is 1, fast will not take one step.

The above cycle will not enter directly.

When the value of K is 2, fast will go to the position of the second node first.

4. Let the two pointers move at the same time.

```
//然后两个一起走
//当fast.next==null的时候，slow所指的位置就是倒数第k个结点
while (fast.next != null) {
//两个一起走
fast = fast.next;
slow = slow.next;
}
return slow;//此时slow指向的就是倒数第k个结点
```

The penultimate node is the node pointed to by slow at this time.

full code

```
public ListNode findKthToTail(int k) {
//k位置不合法
if (k <= 0 || this.head == null) {
return null;
}
//定义一个fast和slow指向head
ListNode fast = this.head;
ListNode slow = this.head;
//先让fast走k-1步
while (k - 1 != 0) {
fast = fast.next;
if (fast == null) {
return null;
}
k--;
}
//然后两个一起走
//当fast.next==null的时候，slow所指的位置就是倒数第k个结点
while (fast.next != null) {
//两个一起走
fast = fast.next;
slow = slow.next;
}
return slow;//此时slow指向的就是倒数第k个结点
}
```

It can be seen that the test on Niuke has passed at this time.

\