给定一个长度为N的数组 arr[] ,任务是找到最长子序列的长度,使其最大元素和最小元素的差不超过整数K。
序列a是序列 b的子序列,如果可以通过删除几个(可能为零)元素从 b 中获得 ????a。例如,[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 。
- 对于它的实现,我们使用二进制搜索或lower_bound,并每次更新 ans 作为先前 ans 的最大值和索引的差异。
下面是上述方法的实现:
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))
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live