📌  相关文章
📜  任意两个元素之间的绝对差不大于X的最长子数组

📅  最后修改于: 2021-05-17 17:55:24             🧑  作者: Mango

给定大小为N的整数数组arr []和整数X ,任务是找到最长的子数组,其中任何两个元素之间的绝对差不大于X。
例子:

天真的方法:一种简单的解决方案是一一考虑所有子数组,找到该子数组的最大和最小元素,并检查它们的差值是否不大于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))