题目:给定一个单向链表,要求找出该链表中倒数第 k 个节点,要求只能遍历一次链表,且空间复杂度为 O(1)。
思路1:为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。但是单向链表的结点只有从前往后的指针而没有从后往前的指针,因此这种思路行不通。
思路2: 既然不能从尾结点开始遍历这个链表,我们还是要从头结点来。假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点。所以我们看下先遍历整个链表得到链表的结点个数n。再从头结点开始往后走n-k+1步就可以得到第n-k+1个结点。但是这个方案,需要我们遍历链表两次,显然不符合题目要求。
思路3:上面我们提到遍历链表两次行不通,我们考虑借助数组这个数组结构,来规避第二次遍历。在第一次遍历时,我们把链表的每个结点都存入到一个数组中,然后通过数组下标可直接获取到倒数第k个结点。但是这个方案需要额外的存储空间,空间复杂度为O(n),显然也不符合题目要求。
思路4:我们定义两个指针,分别叫前指针和后指针。先让前指针指向链表的头指针并开始遍历向前走k-1,后指针保持不动。从第k步开始,后指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当前指针到达链表的尾结点时,后指针正好是倒数第k个结点。
demo:
public class TestDemo {
public static void main(String[] args) {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3&#