单向链表-七牛云2018秋
1.题目描述
输入一个单向链表,输出该链表中倒数第k个节点,链表的倒数第1个节点为链表的尾指针。 比如链表为:
1->2->3->4->5->6->7->8
则其倒数第3
个节点为:6
链表节点定义为:
typedef struct node_ {
int key;
struct node_ *next;
} Node;
函数定义:
Node *the_reciprocal_kth_node(Node *head, int k) {
// 请补全该函数
}
2.题目解析
通过两个指针来解决问题,但要注意代码中的各种边界条件检查。
3.参考答案
#include <bits/stdc++.h>
using namespace std;
// 链表节点 = 数据 + 索引(指针)
struct Node{
int data;
Node *p;
};
Node *the_reciprocal_kth_node(Node *head, int k) {
if(NULL == head) return NULL;
int len = 0;
// 第一遍历链表,获取链表长度
Node* pNode = head;
while(pNode != NULL){
pNode = pNode->p;
++len;
}
if(k > len) return NULL;
// 第二次遍历链表,找到指定节点
int n = len - k;
Node* temp = head;
for(int i=0;i<n;++i){
temp = temp->p;
}
return temp;
}
// 10 7 5 3 2 1
int main() {
// 构造链表
Node root; // 根节点(链表的首节点)
root.data = 10;
Node n1;
n1.data = 7;
root.p = &n1;
Node n2;
n2.data = 5;
n1.p = &n2;
Node n3;
n3.data = 3;
n2.p = &n3;
Node n4;
n4.data = 2;
n3.p = &n4;
Node n5;
n5.data = 1;
n4.p = &n5;
n5.p = NULL; // n5后面没有节点了NULL。
Node *res = the_reciprocal_kth_node(&root,1);
printf("%d\n",res->data);
}
Node *the_reciprocal_kth_node(Node *head, int k) {
if (k < 1) return NULL;
Node *p = head;
int len = 0;
while(p != NULL) {
p = p->next;
++len;
}
// 如果k大于链表长度
if (k > len) return NULL;
// 如果k小于等于链表长度,遍历移动len-k次
p = head;
for(int i=0;i!=(len-k);++i){
p = p->next;
}
return p;
}
另一种思路
Node *the_reciprocal_kth_node(Node *head, int k) {
if (k < 1) return NULL;
Node *slow = head;
Node *fast = head;
int i = k;
for (; i > 0 && fast != NULL; i--) {
fast = fast->next;
}
// 如果k大于链表长度
if (i > 0) return NULL;
// 如果k小于等于链表长度
while (fast != NULL) { // show与fast相隔k,当fast到达1时,show到达k
slow = slow->next;
fast = fast->next;
}
return slow;
}