链表中倒数第K个节点

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

思路:
 倒着数,关联着先进后出的栈。在这里可以采用栈来做,把所有的节点指针进栈,然后再弹出(k-1)个数,现在的栈顶即为所求节点。
时间复杂度O(n),两次遍历
空间复杂度O(n),辅助内存存储全部数据
代码如下:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
    	//栈底层采用的是deque的实现方式,比较复杂,所以这里指定使用轻量级的vector来作为底层实现
    	//有疑惑的可以查看《STL源码剖析》
        stack<ListNode*, vector<ListNode*>> s;
        if (pListHead == NULL || k == 0) {//这里的k是unsigned int类型,所以不会是负数
            return NULL;
        }
        
        while (pListHead) {
            s.push(pListHead);
            pListHead = pListHead->next;
        }
        
        if (s.size() < k) {
            return NULL;
        } else {
            for (int i = 1; i < k; i++) {//这里尽量不要采用k递减的方式,容易出错
                s.pop();
            }
        }
        
        return s.top();//栈定义于函数内部,当函数执行完毕,局部变量内存会被回收,无需考虑内存问题
    }
};

 1.定义两个指针preNode和currNode,两个指针之间相差k,即currNode-preNode = k(我这只是这么写你们看着方便而已,实际上这样是不对的,因为只有RandomAccessIterator才有这种功能。参考C++ Primer 5th P365)。
 2.两个指针同时递增,即它们之间的距离始终相差k。
 3.结束条件:currNode 为 NULL,此时的 preNode 即为所求
时间复杂度O(n),接近两次遍历
空间复杂度O(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) {
        if (k == 0 || pListHead == NULL) {
            return NULL;
        }
        
        ListNode* currNode = pListHead;
        //currNode节点向前移动 K 个位置
        for (int i = 0; i < k; i++) {
            if (currNode == NULL) {
                return NULL;
            }
            currNode = currNode->next;
        }
        
        while(currNode != NULL) {
            pListHead = pListHead->next;
            currNode = currNode->next;
        }
        
        return pListHead;
    }
};

大神代码:

/*
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* currNode = pListHead;
        int i = 0;
        //考虑用一个循环来做
        for (; currNode != NULL; i++) {
            if (i >= k) {
                pListHead = pListHead->next;
            }
            currNode = currNode->next;
        }
        
        return i < k ? NULL : pListHead;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值