题目描述:

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

尾节点是倒数第一个节点

测试用例:  

功能测试(第k个节点在中间、是头节点、是尾节点)

特殊输入测试(链表头节点是nullptr指针、链表的头节点个数小于k、k=0)

解题思路:

1)使用两个指针,一个指针先移动k步,如果链表小于k,终止返回nullptr。然后两个指针同时移动,知道后一个指针移出最后一个节点

//实现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(pListHead==nullptr || k=0)return nullptr; //不要忘记k<0的情况 无符号不用判断k<0时; ListNode* back = pListHead;
//先将指针back移动到第k个元素的位置,索引k的位置
while(back!=nullptr && k>0){ //先判断k=0,然后才是k--。
back=back->next;
k--;
}
if(k>0) //说明链表的长度<k
return nullptr; ListNode* front = pListHead;
while(back!=nullptr){ //back->next!=nullptr 是错误的。
back=back->next;
front=front->next;
} return front;
}
};  

注:尾节点是倒数第一个节点,因此k=1时,front应该指向尾节点,此时back应该是刚好移出尾节点,为空nullptr。

使用两个指针,一个指针先移动k-1步,如果链表小于k,终止返回nullptr。然后两个指针同时移动,知道后一个指针移动到最后一个节点

//实现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(pListHead==nullptr || k==0)return nullptr; //无符号,所以不用判断k<0; ListNode* back = pListHead;
//先将指针back移动到第k-1个元素的位置,
while(back->next!=nullptr && k-1>0){ //为了得知第k个元素是否存在,应该判断back->next!=nullptr而不是back!=nullptr
back=back->next;
k--;
}
if(k>1) //说明链表的长度<k
return nullptr; ListNode* front = pListHead;
while(back->next!=nullptr){ //back移动到最后一个元素即可
back=back->next;
front=front->next;
} return front;
}
};
//实现2
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr || k==0)return nullptr; //无符号,所以不用判断k<0; ListNode* back = pListHead;
//先将指针back移动到第k-1个元素的位置,
/*while(back->next!=nullptr && k-1>0){ //为了得知第k个元素是否存在,应该判断back->next!=nullptr而不是back!=nullptr
back=back->next;
k--;
}
if(k>1) //说明链表的长度<k
return nullptr;*/
for(unsigned int i=0;i<k-1;++i){
if(back->next!=nullptr)
back=back->next;
else
return nullptr;
} ListNode* front = pListHead;
while(back->next!=nullptr){ //back移动到最后一个元素即可
back=back->next;
front=front->next;
} return front;
}
};

    

对于unsigned int类型要格外注意,在写循环或者判断时,常会遇到对变量--;这种情况要格外注意:

因为当unsigned int k=0; --k后,变量的值并不是-1,而是无符号的0xFFFFFFFF,如果此时判断k>0,还是会成立

//该方法是错误的,当k=0是,K-1为0xFFFFFFFF,back会一直向后访问超出数组
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr || k<0)return nullptr; ListNode* back = pListHead;
//先将指针back移动到第k-1个元素的位置
for(unsigned int i=0; i<k-1; ++i){
bask=back->next;
} if(k>1) //说明链表的长度<k
return nullptr; ListNode* front = pListHead;
//back移动到最后一个元素
while(back->next!=nullptr){ //back->next!=nullptr
back=back->next;
front=front->next;
} return front;
}
};

  

相似题目:

求链表的中间节点:如果链表中的节点总数为奇数,则返回中间节点;如果链表总数是偶数,则返回中间两个节点的任意一个。

为了解决这个问题,也可以同时定义两个指针,同时从链表出发,一个指针一次走一步,另一个指针一次走两步。当走的快的指针走到链表末尾时,走的慢的指针正好在链表的中间。

22 链表中倒数第k个节点(第3章 高质量的代码-代码的鲁棒性)的更多相关文章

  1. 【剑指offer】面试题 22. 链表中倒数第 K 个节点

    面试题 22. 链表中倒数第 K 个节点

  2. 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 Offer 22 常规解法 常规解法其实很容易可以想到,只需要先求出链表的长度,然后再次遍历取指定长度的链接即可. package com.walega ...

  3. 【剑指offer】22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 知识点:链表:双指针 题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点. 例 ...

  4. 力扣 - 剑指 Offer 22. 链表中倒数第k个节点

    题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到栈(先进后出)里面,然后pop弹出k个元素就可以了 代码 class Solution ...

  5. LeetCode 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 题意 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点. ​ 例如,一个链表有 6 个 ...

  6. LeetCode 面试题22. 链表中倒数第k个节点

    题目链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/ 输入一个链表,输出该链表中倒数第 ...

  7. C语言面试题22. 链表中倒数第k个节点

    要求:输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5.6. ...

  8. 【剑指Offer】面试题22. 链表中倒数第k个节点

    题目 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5.6. ...

  9. 力扣题解-面试题22. 链表中倒数第K个节点

    题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...

  10. 《剑指offer》面试题22. 链表中倒数第k个节点

    问题描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...

随机推荐

  1. 安装GCC for Red Hat Enterprise Linux Server release 6(64位)

    http://www.cnblogs.com/emanlee/archive/2012/08/11/2633895.html

  2. ubuntu-ln命令

    安装软件完成后,常常需要使用ln命令来将命令重新定义一下路径,就相当于windows中的加入系统环境变量的意思 ~ sudo ln -s /home/spike/Downloads/redis/src ...

  3. 如何用arcgis进行WGS84的投影坐标变换

    转自原文 如何用arcgis进行WGS84的投影坐标变换 通常情况下,要求WGS 84下的投影坐标,选择UTM投影. 1.UTM投影 UTM投影全称为“通用横轴墨卡托投影”UNIVERSAL TRAN ...

  4. HDU 4507

    数位DP. 一般是利用DFS来求数位DP了,结合了记忆化搜索.设dp[i][j][k]为前i位,并且前i位的数位和mod7为j,前i位的数字的表示数字值mod7.为什么可以这样呢?因为继续DFS下去, ...

  5. HDU 3662

    求的是凸包有多少个面. 注意,求的是面.这就需要把同一个面的三角形合并.只需判断两个三角形的法向量是否同向平行. /* 增量法求凸包.选取一个四面体,同时把它各面的方向向量向外,增加一个点时,若该点与 ...

  6. php学习之道:WSDL具体解释(一)

    WSDL文档使用web服务描写叙述语言来定义服务. 文档包含逻辑(抽象)部分和详细部分. 抽象部分用于定义独立于实现的数据类型和消息,详细部分定义一个endpoint怎样实现一个能够与外界进行交互的服 ...

  7. asp.net控件的异步刷新

    需求:我们知道,asp.net控件中的button控件,默认是开启了自己主动回发的,而有时候.我们不想刷新整个界面.而仅仅想局部刷新,可页面中又偏偏用到了.net button控件. 尽管我非常讨厌. ...

  8. 【cl】解决Fail to create the java Virtual Machine

    eclipse打开,提示Fail to create the java Virtual Machine 解决方法: 1.到eclipse安装目录下,找到eclipse.ini 2.按键盘ctrl+F, ...

  9. poj2750--Potted Flower(线段树)

    题目链接:点击打开链接 题目大意:给出n个数排成一个环.求环的最大连续子序列,不能是总序列 建一个线段树来求最大子序列假设仅仅是一个序列.那么求最大连续子序列非常easy,可是假设是一个环,那就要考虑 ...

  10. shell学习五十天----查看进程ps命令

    进程列表 列出进程中最重要的命令便是进程状态命令:ps. ps命令是进程状态(Process Status)的缩写.ps命令用来列出系统中当前执行的那些进程.ps命令列出的是当前那些进程的快照,就是执 ...