面试题 15:链表中倒数第 k 个结点
题目:输入一个链表,输出该链表中倒数第 k 个结点。为了符合大多数人的习惯, 本题从 1 开始计数,即链表的尾结点是倒数第一个结点。例如一个有 6 个结点的 链表,从头结点依次是 1,2,3,4,5,6。倒数第三个结点就是值为 4 的结点。
最初思路:先遍历链表得到链表总长度,然后length-k+1位置的结点就是所求结点。但是需要遍历两遍
改进:用两个指针,两个指针之间距离相差k-1;当第一个指针都到链表尾结点,那么第二个指针就在倒数第k
注意程序的鲁棒性:
链表为空链表,返回null;
k=0,返回空;
k大于链表长度,返回null;
package offer; /*面试题 15:链表中倒数第 k 个结点 题目:输入一个链表,输出该链表中倒数第 k 个结点。为了符合大多数人的习惯, 本题从 1 开始计数,即链表的尾结点是倒数第一个结点。 例如一个有 6 个结点的 链表,从头结点依次是 1,2,3,4,5,6。倒数第三个结点就是值为 4 的结点。 */ public class Problem15 { public static void main(String[] args) { ListNode node1 = new ListNode(); ListNode node2 = new ListNode(); ListNode node3 = new ListNode(); ListNode node4 = new ListNode(); node1.value = 1; node2.value = 2; node3.value = 3; node4.value = 4; node1.nextNode = node2; node2.nextNode = node3; node3.nextNode = node4; Problem15 test = new Problem15(); ListNode result = test.getNode(node1, 1); System.out.println(result.value); } public ListNode getNode(ListNode head,int k){ if(head == null || k <= 0){return null;} ListNode temp = head; for(int i=0; i<k; i++){ //第一个结点先走k步,两个结点相差k-1 if(temp.nextNode!=null) temp = temp.nextNode; else return null;//链表长度小于k } ListNode result = head; while(temp!=null) { temp = temp.nextNode; result = result.nextNode; } return result; } }
同类题目:
1:求链表的中间结点。如果链表中结点总数为奇数,返回中间结点;如果结点总数为偶数,返回中间两个结点任意一个结点。
--同样吗,可以定义两个指针,同时从链表头结点出发,一个指针一次走一步,另一个指针一次走两步,当走的快的结点到达末尾,
慢点的结点刚好在中间。
2:判断一个单链表是否形成了环形结构。两个指针同上,如果快指针追上了慢指针,则是环形结构,否则不是。(走到了链表的末尾)