给定长度为N的数组arr [] ,tark将找到最长子序列的长度,以使其最大元素和最小元素的差不大于整数K。
如果ααa可以通过删除几个(可能为零)元素从b中获得,则序列a是序列b的子序列。例如, [3,1] [3,1]是[3,2,1] [3,2,1]和[4,3,1] [4,3,1]的子序列,但不是[1,3,3,7] [1,3,3,7]及[3,10,4] [3,10,4]的亚序列。
例子:
Input: K = 3, arr[]= {1, 4, 5, 6, 9}
Output: 3
Explanation:
Largest Subarray is {4, 5, 6}
Input: K = 4, arr[]= {1, 2, 3, 4, 5}
Output: 5
Explanation:
Largest Subarray is {1, 2, 3, 4, 5}
天真的方法:
- 生成所有子数组,并在子数组中找到最小值和最大值。
- 计算最小值和最大值之间的差异,如果该差异小于或等于K,则更新答案
时间复杂度: O(N 3 )
高效的方法:想法是首先对数组进行排序,然后使用二进制搜索来优化方法。
- 对给定数组进行排序
- 对于数组中每个不同的元素A [i] ,找到第一个元素A [j]使得(A [j] -A [i])> K。
- 对于它的实现,我们使用Binary search或lower_bound并每次更新ans作为先前ans的最大值和indixes的差。
下面是上述方法的实现:
CPP
// C++ program to find longest
// subarray such that difference
// of max and min is at-most K
#include
using namespace std;
// Function to calculate longest
// subarray with above condition
int findLargestSubarray(
vector& arr,
int N, int K)
{
// Sort the array
sort(arr.begin(), arr.end());
int value1 = arr[0], value2 = 0;
int index1, index2, i, MAX;
index1 = index2 = 0;
i = 0, MAX = 0;
// Loop which will terminate
// when no further elements
// can be included in the subarray
while (index2 != N) {
// first value such that
// arr[index2] - arr[index1] > K
value2 = value1 + (K + 1);
// calculate its index using lower_bound
index2 = lower_bound(arr.begin(),
arr.end(), value2)
- arr.begin();
// index2- index1 will give
// the accurate length
// of suarray then compare
// for MAX length and store
// in MAX variable
MAX = max(MAX, (index2 - index1));
// change the index1
// to next greater element
// than previous one
// and recalculate the value1
index1
= lower_bound(
arr.begin(),
arr.end(), arr[index1] + 1)
- arr.begin();
value1 = arr[index1];
}
// finally return answer MAX
return MAX;
}
// Driver Code
int main()
{
int N, K;
N = 18;
K = 5;
vector arr{ 1, 1, 1, 2, 2,
2, 2, 2, 3,
3, 3, 6, 6, 7,
7, 7, 7, 7 };
cout << findLargestSubarray(arr, N, K);
return 0;
}
输出:
15
时间复杂度: O(N * log(N))