给定大小为N的整数数组arr []和整数X ,任务是找到最长的子数组,其中任何两个元素之间的绝对差不大于X。
例子:
Input: arr = { 8, 4, 2, 6, 7 }, X = 4
Output: 4 2 6
Explanation:
The sub-array described by indexs [1, 3], i.e, { 4, 2, 6 } contains no such difference of two elements which is greater than 4.
Input: arr = { 15, 10, 1, 2, 4, 7, 2}, X = 5
Output: 2 4 7 2
Explanation:
The sub-array described by indexs [3, 6], i.e, { 2, 4, 7, 2 } contains no such difference of two elements which is greater than 5.
天真的方法:一种简单的解决方案是一一考虑所有子数组,找到该子数组的最大和最小元素,并检查它们的差值是否不大于X。在所有此类子阵列中,打印最长的子阵列。
时间复杂度: O(N 3 )
高效方法:想法是使用滑动窗口技术考虑子数组,并使用Map数据结构查找该子数组中的最大和最小元素。
- 首先,窗口的开始和结束指向第0个索引。
- 在每次迭代时,如果End元素不存在,则将其插入Map中,否则,其计数将增加。
- 如果最大元素和最小元素之间的差不大于X ,则更新所需子数组的最大长度,并将该子数组的开头存储在变量中。
- 否则,增加窗口的开始位置,直到最大和最小元素之间的差不大于X。
- 当增加Start时,窗口的大小会减小,并且仅当该元素的计数变为零时,才从Map中删除Start上的元素。
最后,打印具有最长长度的子数组,并且任何两个元素之间的绝对差不大于X。
下面是上述方法的实现:
C++
// C++ program to find the longest sub-array
// where the absolute difference between any
// two elements is not greater than X
#include
using namespace std;
// Function that prints the longest sub-array
// where the absolute difference between any
// two element is not greater than X
void longestSubarray(int* A, int N, int X)
{
// Initialize a variable to store
// length of longest sub-array
int maxLen = 0;
// Initialize a variable to store the
// beginning of the longest sub-array
int beginning = 0;
// Initialize a map to store the maximum
// and the minimum elements for a given window
map window;
// Initialize the window
int start = 0, end = 0;
// Loop througth the array
for (; end < N; end++) {
// Increment the count of that
// element in the window
window[A[end]]++;
// Find the maximum and minimum element
// in the current window
auto minimum = window.begin()->first;
auto maximum = window.rbegin()->first;
// If the difference is not
// greater than X
if (maximum - minimum <= X) {
// Update the length of the longest
// sub-array and store the beginning
// of the sub-array
if (maxLen < end - start + 1) {
maxLen = end - start + 1;
beginning = start;
}
}
// Decrease the size of the window
else {
while (start < end) {
// Remove the element at start
window[A[start]]--;
// Remove the element from the window
// if its count is zero
if (window[A[start]] == 0) {
window.erase(window.find(A[start]));
}
// Increment the start of the window
start++;
// Find the maximum and minimum element
// in the current window
auto minimum = window.begin()->first;
auto maximum = window.rbegin()->first;
// Stop decreasing the size of window
// when difference is not greater
if (maximum - minimum <= X)
break;
}
}
}
// Print the longest sub-array
for (int i = beginning; i < beginning + maxLen; i++)
cout << A[i] << " ";
}
// Driver Code
int main()
{
int arr[] = { 15, 10, 1, 2, 4, 7, 2 }, X = 5;
int n = sizeof(arr) / sizeof(arr[0]);
longestSubarray(arr, n, X);
return 0;
}
Java
// JAVA program to find the longest sub-array
// where the absolute difference between any
// two elements is not greater than X
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
// Function that prints the longest sub-array
// where the absolute difference between any
// two element is not greater than X
static void longestSubarray(int A[], int N, int X)
{
// Initialize a variable to store
// length of longest sub-array
int maxLen = 0;
// Initialize a variable to store the
// beginning of the longest sub-array
int beginning = 0;
// Initialize a map to store the maximum
// and the minimum elements for a given window
TreeMap window = new TreeMap<>();
// Initialize the window
int start = 0, end = 0;
// Loop througth the array
for (; end < N; end++)
{
// Increment the count of that
// element in the window
window.put(A[end],
window.getOrDefault(A[end], 0) + 1);
// Find the maximum and minimum element
// in the current window
int minimum = window.firstKey();
int maximum = window.lastKey();
// If the difference is not
// greater than X
if (maximum - minimum <= X)
{
// Update the length of the longest
// sub-array and store the beginning
// of the sub-array
if (maxLen < end - start + 1) {
maxLen = end - start + 1;
beginning = start;
}
}
// Decrease the size of the window
else {
while (start < end)
{
// Remove the element at start
window.put(A[start],
window.get(A[start]) - 1);
// Remove the element from the window
// if its count is zero
if (window.get(A[start]) == 0) {
window.remove(A[start]);
}
// Increment the start of the window
start++;
// Find the maximum and minimum element
// in the current window
minimum = window.firstKey();
maximum = window.lastKey();
// Stop decreasing the size of window
// when difference is not greater
if (maximum - minimum <= X)
break;
}
}
}
// Print the longest sub-array
for (int i = beginning; i < beginning + maxLen; i++)
System.out.print(A[i] + " ");
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 15, 10, 1, 2, 4, 7, 2 }, X = 5;
// store the size of the array
int n = arr.length;
// Function call
longestSubarray(arr, n, X);
}
}
// This code is contributed by Kingash.
Python3
# Python3 program to find the longest sub-array
# where the absolute difference between any
# two elements is not greater than X
# Function that prints the longest sub-array
# where the absolute difference between any
# two element is not greater than X
def longestSubarray(A, N, X):
# Initialize a variable to store
# length of longest sub-array
maxLen = 0
# Initialize a variable to store the
# beginning of the longest sub-array
beginning = 0
# Initialize a map to store the maximum
# and the minimum elements for a given window
window = {}
# Initialize the window
start = 0
# Loop througth the array
for end in range(N):
# Increment the count of that
# element in the window
if A[end] in window:
window[A[end]] += 1
else:
window[A[end]] = 1
# Find the maximum and minimum element
# in the current window
minimum = min(list(window.keys()))
maximum = max(list(window.keys()))
# If the difference is not
# greater than X
if maximum - minimum <= X:
# Update the length of the longest
# sub-array and store the beginning
# of the sub-array
if maxLen < end - start + 1:
maxLen = end - start + 1
beginning = start
# Decrease the size of the window
else:
while start < end:
# Remove the element at start
window[A[start]] -= 1
# Remove the element from the window
# if its count is zero
if window[A[start]] == 0:
window.pop(A[start])
# Increment the start of the window
start += 1
# Find the maximum and minimum element
# in the current window
minimum = min(list(window.keys()))
maximum = max(list(window.keys()))
# Stop decreasing the size of window
# when difference is not greater
if maximum - minimum <= X:
break
# Print the longest sub-array
for i in range(beginning, beginning + maxLen):
print(A[i], end = ' ')
# Driver Code
arr = [15, 10, 1, 2, 4, 7, 2]
X = 5
n = len(arr)
longestSubarray(arr, n, X)
# This code is contributed by Shivam Singh
2 4 7 2
时间复杂度: O(N * log(N))