1. 题目要求
2. 解答
2.1 数组指针法
开两个指针 a,b
,外循环让 a
往前走,内循环让 b
每次从头走到尾,依次比较 a b
所指的数组的数值。为了避免同一个数对计算两次,固定只考虑 b = a + 1
的情况。时间复杂度
O
(
n
2
)
O(n^2)
O(n2)
#include <iostream>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
int q[n];
int cnt = 0;
for(int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
{
if(q[j] == q[i] + 1)
{
cnt ++;
break;
}
}
printf("%d", cnt);
return 0;
}
2.2 哈希表做法
本题还可以采用哈希表做法,先将所有的数字都插入一个 unordered_set
中,然后遍历数组中的每一个元素 x
,如果在哈希表中找到了 x+1
就表示有一个数对。这种做法时间复杂度
O
(
n
)
O(n)
O(n)。
unordered_set属于C++11 STL 的数据结构,考试时可以选择C++11标准,并及时得到分数反馈。所以可以用到 C++11 的特性,比如for
循环范围遍历。
#include <iostream>
#include <unordered_set>
using namespace std;
int main()
{
unordered_set<int> hash;
int n;
scanf("%d", &n);
while(n --)
{
int x;
scanf("%d", &x);
hash.insert(x);
}
int cnt = 0;
for(auto x: hash) if(hash.count(x + 1)) cnt ++;
printf("%d", cnt);
return 0;
}
3. 总结
这一题因为 n
最大值是 1000
,所以第一种比较普遍的两个指针的做法复杂度
O
(
n
2
)
O(n^2)
O(n2) 也可以接受。第二种用到了 STL
思路简单且复杂度很低,因为哈希表的查询是
O
(
1
)
O(1)
O(1) 的。
现在基本上前两题可以拿下了,第三题看情况(模拟有时候很难),第四第五题因为真正涉及到了算法,现在还在学习中。推荐算法平台 AcWing 上的算法基础课。