给定N个整数的数组arr []和整数K ,我们的任务是找到最长子数组的长度,以使得对于子数组中所有可能的对,元素之间的绝对差小于或等于K。
例子:
Input: arr[] = {2, 4, 5, 5, 5, 3, 1}, K = 0
Output: 3
Explanation:
The possible subarray with difference in elements as 0 is {5, 5, 5} whose length is 3. Hence the output is 3.
Input: arr[] = {1, 2, 3, 6, 7}, K = 2
Output: 3
Explanation:
The possible subarray with difference in elements at most 2 is {1, 2, 3} whose length is 3. Hence the output is 3.
天真的方法:
为了解决上述问题,天真的方法是使用蛮力方法,该方法将生成给定数组的所有可能的子数组,并检查子数组的最大元素和最小元素之间的差是否最大为K。如果是这样,则以最大长度更新当前子数组的长度。完成所有操作后,打印子数组的最大长度。
下面是上述方法的实现:
C++
// C++ implementation to find the Longest subarray
// of the given array with absolute difference between
// elements less than or equal to integer K
#include
using namespace std;
int computeLongestSubarray(int arr[], int k, int n)
{
// maxLength is 1 because k >= 0,
// a single element, subarray will always
// have absolute difference zero
int maxLength = 1;
// Check for all possible subarrays
for(int i = 0; i < n; i++)
{
// Initalization of minimum &
// maximum of current subarray
int minOfSub = arr[i];
int maxOfSub = arr[i];
for(int j = i + 1; j < n; j++)
{
// Update the values for minimum & maximum
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
// Check if current subarray satisfies
// the given condition
if ((maxOfSub - minOfSub) <= k)
{
int currLength = j - i + 1;
// Update the value for maxLength
if (maxLength < currLength)
maxLength = currLength;
}
}
}
// Return the final result
return maxLength;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 3, 6, 7 };
int k = 2;
int n = sizeof(arr) / sizeof(arr[0]);
int maxLength = computeLongestSubarray(arr, k, n);
cout << (maxLength);
}
// This code is contributed by chitranayal
Java
// Java implementation to find the Longest subarray
// of the given array with absolute difference between
// elements less than or equal to integer K
class GFG {
public static int computeLongestSubarray(int arr[],
int k)
{
// maxLength is 1 because k >= 0,
// a single element, subarray will always
// have absolute difference zero
int maxLength = 1;
// Check for all possible subarrays
for (int i = 0; i < arr.length; i++) {
// Initalization of minimum &
// maximum of current subarray
int minOfSub = arr[i];
int maxOfSub = arr[i];
for (int j = i + 1; j < arr.length; j++) {
// Update the values for minimum & maximum
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
// Check if current subarray satisfies
// the given condition
if ((maxOfSub - minOfSub) <= k) {
int currLength = j - i + 1;
// Update the value for maxLength
if (maxLength < currLength)
maxLength = currLength;
}
}
}
// Return the final result
return maxLength;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computeLongestSubarray(arr, k);
System.out.println(maxLength);
}
}
Python3
# Python3 implementation to find the
# Longest subarray of the given array
# with absolute difference between
# elements less than or equal to integer K
def computeLongestSubarray (arr, k, n):
# maxLength is 1 because k >= 0,
# a single element, subarray will always
# have absolute difference zero
maxLength = 1
# Check for all possible subarrays
for i in range(n):
# Initialization of minimum &
# maximum of current subarray
minOfSub = arr[i]
maxOfSub = arr[i]
for j in range(i + 1, n):
# Update the values for
# minimum & maximum
if (arr[j] > maxOfSub):
maxOfSub = arr[j]
if (arr[j] < minOfSub):
minOfSub = arr[j]
# Check if current subarray
# satisfies the given condition
if ((maxOfSub - minOfSub) <= k):
currLength = j - i + 1
# Update the value for maxLength
if (maxLength < currLength):
maxLength = currLength
# Return the final result
return maxLength
# Driver Code
if __name__ == '__main__':
arr = [ 1, 2, 3, 6, 7 ]
k = 2
n = len(arr)
maxLength = computeLongestSubarray(arr, k, n)
print(maxLength)
# This code is contributed by himanshu77
C#
// C# implementation to find the longest subarray
// of the given array with absolute difference between
// elements less than or equal to integer K
using System;
class GFG
{
public static int computelongestSubarray(int []arr,
int k)
{
// maxLength is 1 because k >= 0,
// a single element, subarray will always
// have absolute difference zero
int maxLength = 1;
// Check for all possible subarrays
for (int i = 0; i < arr.Length; i++)
{
// Initalization of minimum &
// maximum of current subarray
int minOfSub = arr[i];
int maxOfSub = arr[i];
for (int j = i + 1; j < arr.Length; j++)
{
// Update the values for minimum & maximum
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
// Check if current subarray satisfies
// the given condition
if ((maxOfSub - minOfSub) <= k)
{
int currLength = j - i + 1;
// Update the value for maxLength
if (maxLength < currLength)
maxLength = currLength;
}
}
}
// Return the readonly result
return maxLength;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computelongestSubarray(arr, k);
Console.WriteLine(maxLength);
}
}
// This code is contributed by shikhasingrajput
Java
// Java implementation to find the Longest
// subarray of the given array with absolute
// difference between elements less than or equal
// to integer K using Heaps
import java.util.*;
class GFG {
public static int computeLongestSubarray(int arr[],
int k)
{
// Stores the maximum length subarray so far
int maxLength = 0;
Deque maxHeap = new LinkedList<>();
Deque minHeap = new LinkedList<>();
// Marks to the beginning and end
// pointer for current subarray
int beg = 0, end = 0;
while (end < arr.length) {
// Stores the current element being
// added to the subarray
int currEl = arr[end];
// Remove indices of all elements smaller
// than or equal to current from maxHeap
while (maxHeap.size() > 0 &&
arr[maxHeap.peekLast()] <= currEl)
maxHeap.removeLast();
// Add current element's index to maxHeap
maxHeap.addLast(end);
// Remove indices of all elements larger
// than or equal to current from minHeap
while (minHeap.size() > 0 &&
arr[minHeap.peekLast()] >= currEl)
minHeap.removeLast();
// Add current element's index to minHeap
minHeap.addLast(end);
// Index of maximum of current subarray
int maxOfSub = arr[maxHeap.peekFirst()];
// Index of minimum of current subarray
int minOfSub = arr[minHeap.peekFirst()];
// check if the largest possible difference
// between a pair of elements <= k
if (maxOfSub - minOfSub <= k) {
// Length of current subarray
int currLength = end - beg + 1;
// Update maxLength
if (maxLength < currLength)
maxLength = currLength;
}
else {
// If current subarray doesn't satisy
// the condition then remove the starting
// element from subarray that satisy
// increment the beginning pointer
beg++;
// Remove elements from heaps that
// are not in the subarray anymore
while (minHeap.size() > 0 &&
minHeap.peekFirst() < beg)
minHeap.removeFirst();
while (maxHeap.size() > 0 &&
maxHeap.peekFirst() < beg)
maxHeap.removeFirst();
}
end++;
}
// Return the final answer
return maxLength;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computeLongestSubarray(arr, k);
System.out.println(maxLength);
}
}
Python3
# Python3 implementation to find the Longest
# subarray of the given array with absolute
# difference between elements less than or equal
# to integer K using Heaps
from collections import deque
def computeLongestSubarray(arr, k):
# Stores the maximum length subarray so far
maxLength = 0
maxHeap = []
minHeap = []
# Marks to the beginning and end
# pointer for current subarray
beg = 0
end = 0
while (end < len(arr)):
# print(end)
# Stores the current element being
# added to the subarray
currEl = arr[end]
# Remove indices of all elements smaller
# than or equal to current from maxHeap
while (len(maxHeap) > 0 and arr[maxHeap[-1]] <= currEl):
del maxHeap[-1]
# Add current element's index to maxHeap
maxHeap.append(end)
# Remove indices of all elements larger
# than or equal to current from minHeap
while (len(minHeap) > 0 and arr[minHeap[-1]] >= currEl):
# print(minHeap[-1])
del minHeap[-1]
# Add current element's index to minHeap
minHeap.append(end)
# Index of maximum of current subarray
maxOfSub = arr[maxHeap[0]]
# Index of minimum of current subarray
minOfSub = arr[minHeap[0]]
# check if the largest possible difference
# between a pair of elements <= k
if (maxOfSub - minOfSub <= k):
# Length of current subarray
currLength = end - beg + 1
# Update maxLength
if (maxLength < currLength):
maxLength = currLength
else:
# If current subarray doesn't satisy
# the condition then remove the starting
# element from subarray that satisy
# increment the beginning pointer
beg += 1
# Remove elements from heaps that
# are not in the subarray anymore
while (len(minHeap) > 0 and minHeap[0] < beg):
del minHeap[0]
while (len(maxHeap) > 0 and maxHeap[0] < beg):
del maxHeap[0]
end += 1
# Return the final answer
return maxLength
# Driver code
if __name__ == '__main__':
arr = [1, 2, 3, 6, 7]
k = 2
maxLength = computeLongestSubarray(arr, k)
print(maxLength)
# This code is contributed by mohit kumar 29
3
时间复杂度: O(n 2 )
高效方法:
为了优化上述方法,我们的想法是使用堆数据结构。初始化一个minHeap ,它将存储当前子数组的索引,以使元素以升序排列,其中最小的元素出现在顶部;而一个maxHeap ,它将存储当前子数组的索引,以使元素以降序排列,其中最大的元素显示在顶部。然后遍历整个数组,并为每次迭代检查是否:
- 所有子数组元素都满足maxOfSub-minOfSub <= k的条件,然后我们将到目前为止的maxLength与当前子数组的长度进行比较,并将maxLength更新为maxLength或当前子数组长度的最大值。
- 如果不满足条件,则将子数组的开始指针增加1,并从minHeap和maxHeap中删除所有不包括在新子数组中的索引。
- 每次迭代后,我们通过增加结束指针来增加子数组的长度。
下面是上述方法的实现:
Java
// Java implementation to find the Longest
// subarray of the given array with absolute
// difference between elements less than or equal
// to integer K using Heaps
import java.util.*;
class GFG {
public static int computeLongestSubarray(int arr[],
int k)
{
// Stores the maximum length subarray so far
int maxLength = 0;
Deque maxHeap = new LinkedList<>();
Deque minHeap = new LinkedList<>();
// Marks to the beginning and end
// pointer for current subarray
int beg = 0, end = 0;
while (end < arr.length) {
// Stores the current element being
// added to the subarray
int currEl = arr[end];
// Remove indices of all elements smaller
// than or equal to current from maxHeap
while (maxHeap.size() > 0 &&
arr[maxHeap.peekLast()] <= currEl)
maxHeap.removeLast();
// Add current element's index to maxHeap
maxHeap.addLast(end);
// Remove indices of all elements larger
// than or equal to current from minHeap
while (minHeap.size() > 0 &&
arr[minHeap.peekLast()] >= currEl)
minHeap.removeLast();
// Add current element's index to minHeap
minHeap.addLast(end);
// Index of maximum of current subarray
int maxOfSub = arr[maxHeap.peekFirst()];
// Index of minimum of current subarray
int minOfSub = arr[minHeap.peekFirst()];
// check if the largest possible difference
// between a pair of elements <= k
if (maxOfSub - minOfSub <= k) {
// Length of current subarray
int currLength = end - beg + 1;
// Update maxLength
if (maxLength < currLength)
maxLength = currLength;
}
else {
// If current subarray doesn't satisy
// the condition then remove the starting
// element from subarray that satisy
// increment the beginning pointer
beg++;
// Remove elements from heaps that
// are not in the subarray anymore
while (minHeap.size() > 0 &&
minHeap.peekFirst() < beg)
minHeap.removeFirst();
while (maxHeap.size() > 0 &&
maxHeap.peekFirst() < beg)
maxHeap.removeFirst();
}
end++;
}
// Return the final answer
return maxLength;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computeLongestSubarray(arr, k);
System.out.println(maxLength);
}
}
Python3
# Python3 implementation to find the Longest
# subarray of the given array with absolute
# difference between elements less than or equal
# to integer K using Heaps
from collections import deque
def computeLongestSubarray(arr, k):
# Stores the maximum length subarray so far
maxLength = 0
maxHeap = []
minHeap = []
# Marks to the beginning and end
# pointer for current subarray
beg = 0
end = 0
while (end < len(arr)):
# print(end)
# Stores the current element being
# added to the subarray
currEl = arr[end]
# Remove indices of all elements smaller
# than or equal to current from maxHeap
while (len(maxHeap) > 0 and arr[maxHeap[-1]] <= currEl):
del maxHeap[-1]
# Add current element's index to maxHeap
maxHeap.append(end)
# Remove indices of all elements larger
# than or equal to current from minHeap
while (len(minHeap) > 0 and arr[minHeap[-1]] >= currEl):
# print(minHeap[-1])
del minHeap[-1]
# Add current element's index to minHeap
minHeap.append(end)
# Index of maximum of current subarray
maxOfSub = arr[maxHeap[0]]
# Index of minimum of current subarray
minOfSub = arr[minHeap[0]]
# check if the largest possible difference
# between a pair of elements <= k
if (maxOfSub - minOfSub <= k):
# Length of current subarray
currLength = end - beg + 1
# Update maxLength
if (maxLength < currLength):
maxLength = currLength
else:
# If current subarray doesn't satisy
# the condition then remove the starting
# element from subarray that satisy
# increment the beginning pointer
beg += 1
# Remove elements from heaps that
# are not in the subarray anymore
while (len(minHeap) > 0 and minHeap[0] < beg):
del minHeap[0]
while (len(maxHeap) > 0 and maxHeap[0] < beg):
del maxHeap[0]
end += 1
# Return the final answer
return maxLength
# Driver code
if __name__ == '__main__':
arr = [1, 2, 3, 6, 7]
k = 2
maxLength = computeLongestSubarray(arr, k)
print(maxLength)
# This code is contributed by mohit kumar 29
3
时间复杂度: O(n),因为数组的每个元素仅在堆中添加和删除一次。