本题来自《剑指offer》 链表中倒数第k个节点
题目:
输入一个链表,输出该链表中倒数第k个结点。
思路:
倒数第k个节点,而且只能访问一遍链表,定义两个节点,两者之间相差k个距离,遍历到尾节点,则便找到了倒数k节点了。
考虑代码的鲁棒性。代码的鲁棒是指程序能够判断输入是否合乎规范要求,并对不合理的输入给予合理的处理。
1.如果传入的根节点是空:直接返回空
2.传入的数据少于k个:在遍历前k个节点时候,如果发现为空,则直接返回空
3.传入的k为小于或者等于0:直接返回空
4.正常的数据,first和second两者相隔k,依次遍历
C++ Code:
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if (!pListHead || k<=0){ //鲁棒性检测,如果头指针为空或者k小于0直接返回空 return NULL; } ListNode* first = pListHead; ListNode* second = pListHead; for (int i=0;i<k;i++){ //第二个节点和第一个节点相隔k个距离 if (!second){ return NULL; } second = second->next; } while (second){ //第一个和第二个节点依次遍历,直到尾节点为止 first = first->next; second = second->next; } return first; //第一个节点便是倒数第k个节点 } };
Python Code:
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def FindKthToTail(self, head, k): # write code here if not head or k <=0 : #如果head为空或者k小于0,直接返回空 return None first,second = head,head for i in range(k): #第二个指针和第一个指针相差k个距离 if not second : #考虑,如果个数都小于k,则直接返回空 return None second = second.next while second: #两者同时遍历,直到道尾节点 first = first.next second = second.next return first #第一个节点就是倒数k个节点了
总结:
要考虑输入参数的鲁棒性,输入可能取得所有值,比如边界值,要考虑这些值的处理方法。
类似题目:
A.求链表的中间节点:如果链表的中间节点总数为奇数,返回中间节点,如果为偶数,返回中间的其中一个。
定义两个节点,第一个节点first一次跨一步。
第二个节点second一次跨两步,当该节点是尾节点时候,刚好第一个节点是中间节点。
B.判断一个链表是否形成了环形节点
同上,定义两个指针,慢指针一次跨一步,快的指针一次跨两步,如果快的赶上了慢的,则表明是环形,如果快的指针走到了链表的末尾即为空,则表明不是环形链表。