写在所有的前面:
本文采用C语言实现代码
目录
- 写在所有的前面:
- 题目说明
- 题目:
- 题目出处
- 题目描述Description
- 输入Input
- 输出Output
- 样例Sample
- 限制Hint
- 解答说明
- 方案1
- 解题思路
- 一般情况
- 特殊情况
- 代码实现
- 其他解释
题目说明
题目:
题目出处
pta
《数据结构》
题目描述Description
请设计时间和空间上都尽可能高效的算法,在不改变链表的前提下,求链式存储的线性表的倒数第m(>0)个元素。
如果这样的元素不存在,则返回一个错误标志 ERROR = -1。
输入Input
第一行:一个整数n,线性表元素个数
第二行:n个整数,即线性表数列
第三行:一个整数m,即查找倒数第m个
输出Output
查找到的倒数第m个数字
样例Sample
输入:
5
1 2 4 5 6
3
输出:
4
限制Hint
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
解答说明
方案1
解题思路
双指针,间隔为m,遍历一次即可
一般情况
前指针先走,间隔值 x ++,当两者间隔 x == m 时,后指针再走,
前指针遍历完时,后指针所指即为倒数第m个数字。
特殊情况
x < m :倒数的 m > 总个数 n,即没有查找到,返回ERROR
代码实现
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <stdlib.h>#define ERROR -1typedef int ElementType;typedef struct Node* PtrToNode;//指针类型struct Node {ElementType Data;//数据域 intPtrToNode Next;//指针域
};typedef PtrToNode List;//指针重命名为ListList Read()
{int n; //链节个数scanf("%d", &n); //输入链节个数List p = (List)malloc(sizeof(Node)); //定义当前指针并开辟头指针链结空间p->Data = 0; //链表长度p->Next = NULL; //初始化头指针List head = p; //真正的头指针for (int i = 0; i < n; i++) //输入n次数据{p->Next = (List)malloc(sizeof(Node)); //开辟下一链结空间scanf("%d", &p->Next->Data); //输入下一链结内容p = p->Next; //更新当前指针p到下一个p->Next = NULL;head->Data++; //更新链表长度++}return head; //返回头指针
}ElementType Find(List L, int m)
{if (L->Next == NULL)return ERROR; //空链表List f = L->Next, l = L->Next; //前指针 f 指向头结点 1,后指针 l 指向结点 1int x = 1; //初始化两指针差值while (l->Next) //f 指针指向最后一个结点{l = l->Next; //更新后指针if (x == m) //差值已经达到 mf = f->Next; //更新前指针elsex++; //更新差值}if (x == m) //差值已经到达 mreturn f->Data; //返回倒数第 m 个值elsereturn ERROR; //返回未找到
}int main()
{List L; //定义链表头指针int m; //查询倒数第m个L = Read(); //输入链表内容scanf("%d", &m); //输入mprintf("%d\n", Find(L, m)); //输出查询内容return 0;
}
其他解释
原为函数题,只要求写ElementType Find( List L, int m );
函数,个人把它补完了,双指针的方法应该是在单链表且固定为尾插法输入的情况下,最优化的方法了…吧?