【剑指offer】链表——014 链表中倒数第k个结点

题目描述

输入一个链表,输出该链表中倒数第k个结点。

题目分析

题目提供的是单向链表,仅有next指针,即仅可从头到尾访问。该问题主要集中在两个点:

  1. 判断k的值是否大于链表的长度;
  2. 如何找到倒数第k个结点:
    • 利用栈的“先进后出”的特点,作k-1次出栈操作,返回栈顶元素;
    • 设链表长度为n,倒数第k个结点就是第(n-k+1)个结点,可以用数组或者快慢指针法实现。

解题

利用栈

利用C++STL中的stack解决该问题,主要思路如下:

  1. 遍历链表,并让链表结点入栈;
  2. 判断stack的长度与k的大小关系;
  3. 出栈k-1次,返回栈顶元素。

代码

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        stack<ListNode*> s;
        while(pListHead != NULL){
            s.push(pListHead);
            pListHead = pListHead->next;
        }
        if(s.size()<k || k <= 0)
            return NULL;
        while(k > 1){
            s.pop();
            k--;
        }
        return s.top();
    }
};

双指针:快慢指针

利用双指针法定位到第(n-k+1)个结点,主要思路如下:

  1. 定义两个指针均赋值头结点;
  2. 其中一个指针先走k步,定义为快指针,另一个为慢指针;
  3. 判断此时快指针是否为NULL,否是,则k大于链表长度;
  4. 否则,快慢指针同时往下走,当快指针为NULL时,即尾结点下一个位置时,慢指针指向的即为第(n-k+1)个结点。

代码

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode* pFast = pListHead;
        ListNode* pSlow = pListHead;
        if(k == 0)
            return NULL;
        for(int i = 0; i < k; i++){
            if(pFast == NULL)
                return NULL;
            pFast = pFast->next;
        }
        while(pFast != NULL){
            pFast = pFast->next;
            pSlow = pSlow->next;
        }
        return pSlow;
    }
};

暴力解法

定义结点数组,因为数组元素从下标0开始存储,所以数组[n-k]即为第(n-k+1)个结点。

代码

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode* node[10010];
        int length = 0;
        while(pListHead != NULL){
            node[length++] = pListHead;
            pListHead = pListHead->next;
        }
        return k > length ? NULL : node[length-k];
        
    }
};

以上思路为个人想法和网络各位大佬的题解的结合,欢迎讨论与指正。

发布了3 篇原创文章 · 获赞 5 · 访问量 73

猜你喜欢

转载自blog.csdn.net/garlicup/article/details/105072949