先介绍一下暴力枚举,有的时候我们要对一个数组进行i和j的双重循环枚举:
当i=0时,j要从下标1遍历到5。时间复杂度为O(N^2)
双指针的思路是什么呢?就是j下标并不需要从i+1开始重新向后枚举一遍,而是随着i向后移动,j也向后移动。
从图中我们可以看到j一直是往右走,不会出现往左移动,当然前提的保证数组是有序的,这样的时间复杂度为O(N)
/*
给定N个整数A1,A2.....An,以及一个正整数K,问在所有的大于等于K的两个数的差(Ai-Aj)中,最小的差是多少。
数据范围 n<=100000
思路:
1.首先对数组排序
2.枚举两个数中的较小的是A[i],较大的是A[j],也就是最小的A[j]-A[i]>=k
*/
#include <iostream>
#include <algorithm>
using namespace std;
int n, k, ans;
#define MAX 100000
int a[MAX];
int main()
{
cin >> n >> k;
for (int i = 0; i < n;i++)
{
cin >> a[i];
}
sort(a,a+n);
if (a[n - 1] - a[0]<k)
{
cout << "no solution" << endl;
return 0;
}
ans = a[n - 1] - a[0]; //求出最大值
for (int i = 0,j=0; i < n;i++)
{
while (j < n && a[j] - a[i] < k) j++;
if (a[j]-a[i]>=k && a[j]-a[i]<ans)
{
ans = a[j] - a[i];
}
}
cout << ans << endl;
return 0;
}