先看问题描述:
给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字。
输入格式:
输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理)。
输出格式:
输出倒数第K个位置上的数据。如果这个位置不存在,输出错误信息NULL。
输入样例:
4 1 2 3 4 5 6 7 8 9 0 -1
输出样例:
7
第一步:读题,找关键词,并摘取。
题目大意不多说了哈,直接找关键词。 关键词:
1.高效的算法(不完美的手写算法不可取,很可能超时,当然大佬自行略过)
2.以负整数表示结尾。
↑摘下眼镜好好康康,是负整数,不是-1哦。
第二步:分析思路:
学习过C++的STL库的小伙伴都知道,C++已经贴心的为我们封装好了现成的双向循环链表:list, 拿来直接用就好了。 (没接触过不要紧, 文章最下面有详细的list教学。) .
首先,输入数据,压入list, 第二步,判定K值,第三步,调用函数输出。
第三步:代码:
#include <iostream>
#include <cstdio>
#include <list>
using namespace std ;
int main()
{
list <int> l ;
int n ; //倒数第n项
cin >> n ;
int x ; //输入的值
int num = 0 ; //计数器
while ( scanf("%d",&x) && x >= 0 ) {
l.push_back(x) ;
num++ ;
}
//如果不存在
if( num < n ) {
cout << "NULL" ;
return 0 ;
}
list <int>::iterator it ;
it = l.end() ;
it-- ;
advance(it,-(n-1)) ;
cout << *it ;
return 0 ;
}
总结:比较水, 但是可装13 优化的地方很多,比如我们很难想到用advance()这个函数去代替循环。再或者用num计数器代替 size()也可以省下很多时间。
附录:list容器的用法:
常用声明方法: list L ;
1.赋值:L.assign()
2.判定是否为空:L.empty() 空为1
3.计算大小:L.size() //目前存储的空间
L.max_size() // 容器的最大容量 (容器也有大小,不是无穷的 比long long 小)
4.排序:sort() 对整型,浮点型,字符型进行排序 (升序) 还可以对结构体,容器排序。
压入元素:L.push_back() ; L.push_front()
插入元素:L.insert(i,x) ; L.insert(i,n,x) L.insert(i,L.begin(),L.end())
删除元素:L.pop_back() ; L.pop_front() L.erase(it) ;
特殊的1:移除元素:L.remove(x) ;
移除前:5 3 5 3 5
L.remove(3) ;
移除后:5 5 5
特殊的2:合并容器:L1.merge(L2) 把L2的所有值给L1 且升序排序
特殊的3:合并容器:L1.splice(L2) 把L2的所有值给L1 且不排序,只连接
特殊的4:因为list迭代器不像vector迭代器那样灵活(因为二者存储方式不同),因此用iterator中的advance函数: advance(it,5) :则输出第六个函数