【剑指offer】14-链表中倒数第k个结点

本文系《剑指offer》的刷题记录,通过牛客网在线平台测试通过。
在线测试平台:牛客网
编程资料获取:CodeLab

1-Description

输入一个链表,输出该链表中倒数第k个结点链表定义如下:

struct ListNode {
      int val;
       struct ListNode *next;
     ListNode(int x) :
           val(x), next(NULL) {
      }
};

2-Solution

  • 第一种方法很容易想到,就是分两次进行遍历,第一次得到总的结点数,第二次直接遍历到倒数第k个结点,下面是代码实现:
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode* ph1 = pListHead;//辅助指针
        int numnode = 0;//结点数
        if(pListHead == NULL || k <= 0)  return NULL;//代码的鲁棒性
        while(ph1 != NULL){//第一遍遍历得到结点数,直到当前结点为空
            ph1 = ph1->next;
            numnode++;
        }
        if(k > numnode) return NULL;//倒数的位置超限
        else{
            for(int i = 0; i < numnode - k; ++i){//第二次遍历找到倒数第k个结点
                pListHead = pListHead->next;
            }
            return pListHead;
        }
    }
};
  • 这里提供第二种方法,首先定义两个指针,第一个指针从链表的头指针开始遍历,向前走k-1步,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。注意的是这两个指针之间距离保持在k-1,所以,当第一个指针(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个指针。下图展示了在有6个结点的链表种找倒数第3个结点的过程:
    【剑指offer】14-链表中倒数第k个结点_第1张图片

下面是解决代码:

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(pListHead == NULL||k <= 0)  return NULL;
        ListNode* ppre = pListHead;
        ListNode* plast = pListHead;       
        for(int i = 0; i < k - 1; i++){
            if(ppre->next != NULL){
                ppre = ppre->next;
            }else{
                return NULL;//说明k大于链表结点数,直接返回
            }
        }
        while(ppre->next != NULL){//同时移动两个指针
            ppre = ppre->next;
            plast = plast->next;
        }
        return plast;
    }
};

你可能感兴趣的:(笔试)