题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
// 本题主要是鲁棒性检测 两个if条件的内容。第二个if不能用p!=NULL 是因为,p定义指的是最后一共节点,如果最后p是NULL(最后一共节点的下一个节点)了,就失去意义了。
ListNode *findK(ListNode *head, int k) { if (head == NULL || k < 1) return 0; ListNode *p = head; // 指向倒数第一个节点 for (int i = 0; i < k- 1; ++i) { if (p -> m_pNext != NULL) p = p -> m_pNext; // 节点总数小于k else return NULL; } ListNode *q = head; // 倒数第k个节点 while (p -> m_pNext != NULL) { p = p -> m_pNext; q = q -> m_pNext; } return q; }扩展: 求链表的中间节点:如果链表节点数是奇数,返回中间节点,否则返回中间两个节点任一个。
定义一个快指针一次走两步,一个慢指针一次走一步。快指针走到末尾慢指针指的就是答案
ListNode *find_mid(ListNode *head) { if(head == NULL) return NULL; ListNode *slow, *fast; slow = fast = head; /*快慢指针都指向第一个节点*/ while (fast != NULL && fast->next != NULL && fast->next->next != NULL) { slow = slow->next; /*慢指针每次走一步*/ fast = fast->next->next; /*快指针每次走两步*/ } return slow; }