📌  相关文章
📜  堆之间元素之间的绝对差小于或等于K的最长子数组

📅  最后修改于: 2021-05-19 19:31:04             🧑  作者: Mango

给定N个整数的数组arr []和整数K ,我们的任务是找到最长子数组的长度,以使得对于子数组中所有可能的对,元素之间的绝对差小于或等于K。
例子:

天真的方法:
为了解决上述问题,天真的方法是使用蛮力方法,该方法将生成给定数组的所有可能的子数组,并检查子数组的最大元素和最小元素之间的差是否最大为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),因为数组的每个元素仅在堆中添加和删除一次。