📌  相关文章
📜  最长的子数组,任意两个不同值之间的差值恰好为K

📅  最后修改于: 2021-04-24 04:03:01             🧑  作者: Mango

给定长度为N的数组arr []和整数K ,任务是找到最长的子数组,其中任意两个Distict值之间的差等于K。打印获得的最长子数组的长度。否则,如果未获得此类子数组,则打印-1

例子:

天真的方法:

  • 一个简单的解决方案是一一考虑所有子数组,然后查找仅包含两个不同值且这两个值之间的差为K的子数组。不断更新获得的子数组的最大长度。
  • 最后打印获得的最大长度。

时间复杂度: O(N 3 )
辅助空间: O(N)

高效方法:
可以观察到,对于任何子数组而言,由两个元素之差恰好为K的元素组成,子数组必须仅由两个不同的值组成。因此,可以通过使用set来找到仅具有两个不同值且差异为K的最长子数组,从而进一步优化上述方法。请按照以下步骤解决问题:

  • 从数组的起始索引开始第一个子数组。
  • 将该元素插入集合。继续至下一个元素,并检查该元素是否与前一个元素相同或绝对差为K。
  • 如果是这样,请将该元素插入集合,然后继续增加子数组的长度。一旦找到第三个不同的元素,将当前子数组的长度与子数组的最大长度进行比较,并进行相应的更新。
  • 将获得的新元素更新到集合中,然后重复上述步骤。
  • 遍历整个数组后,打印获得的最大长度。

下面是上述方法的实现:

C++
// C++ implementation to find the
// longest subarray consisting of
// only two values with difference K
#include 
using namespace std;
 
// Function to return the length
// of the longest sub-array
int longestSubarray(int arr[], int n,
                    int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    set s;
 
    for (i = 0; i < n - 1; i++) {
        // Store 1st element of
        // sub-array into set
        s.insert(arr[i]);
 
        for (j = i + 1; j < n; j++) {
            // Check absolute difference
            // between two elements
 
            if (abs(arr[i] - arr[j]) == 0
                || abs(arr[i] - arr[j]) == k) {
 
                // If the new element is not
                // present in the set
                if (!s.count(arr[j])) {
 
                    // If the set contains
                    // two elements
                    if (s.size() == 2)
                        break;
 
                    // Otherwise
                    else
                        s.insert(arr[j]);
                }
            }
            else
                break;
        }
 
        if (s.size() == 2) {
 
            // Update the maximum
            // length
            Max = max(Max, j - i);
 
            // Remove the set
            // elements
            s.clear();
        }
        else
            s.clear();
    }
 
    return Max;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = sizeof(arr)
            / sizeof(arr[0]);
    int K = 1;
 
    int length = longestSubarray(
        arr, N, K);
 
    if (length == 1)
        cout << -1;
    else
        cout << length;
 
    return 0;
}


Java
// Java implementation to find the
// longest subarray consisting of
// only two values with difference K
import java.util.*;
 
class GFG{
 
// Function to return the length
// of the longest sub-array
static int longestSubarray(int arr[], int n,
                        int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    HashSet s = new HashSet();
 
    for(i = 0; i < n - 1; i++)
    {
         
        // Store 1st element of
        // sub-array into set
        s.add(arr[i]);
 
        for(j = i + 1; j < n; j++)
        {
             
            // Check absolute difference
            // between two elements
            if (Math.abs(arr[i] - arr[j]) == 0 ||
                Math.abs(arr[i] - arr[j]) == k)
            {
                 
                // If the new element is not
                // present in the set
                if (!s.contains(arr[j]))
                {
                     
                    // If the set contains
                    // two elements
                    if (s.size() == 2)
                        break;
 
                    // Otherwise
                    else
                        s.add(arr[j]);
                }
            }
            else
                break;
        }
        if (s.size() == 2)
        {
             
            // Update the maximum
            // length
            Max = Math.max(Max, j - i);
 
            // Remove the set
            // elements
            s.clear();
        }
        else
            s.clear();
    }
    return Max;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = arr.length;
    int K = 1;
    int length = longestSubarray(arr, N, K);
 
    if (length == 1)
        System.out.print(-1);
    else
        System.out.print(length);
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 implementation to find the 
# longest subarray consisting of 
# only two values  with difference K
 
# Function to return the length 
# of the longest sub-array
def longestSubarray (arr, n, k):
 
    Max = 1
 
    # Initialize set
    s = set()
 
    for i in range(n - 1):
 
        # Store 1st element of
        # sub-array into set
        s.add(arr[i])
 
        for j in range(i + 1, n):
             
            # Check absolute difference
            # between two elements
            if (abs(arr[i] - arr[j]) == 0 or
                abs(arr[i] - arr[j]) == k):
 
                # If the new element is not
                # present in the set
                if (not arr[j] in s):
 
                    # If the set contains
                    # two elements
                    if (len(s) == 2):
                        break
 
                    # Otherwise
                    else:
                        s.add(arr[j])
                         
            else:
                break
 
        if (len(s) == 2):
 
            # Update the maximum length
            Max = max(Max, j - i)
 
            # Remove the set elements
            s.clear()
 
        else:
            s.clear()
 
    return Max
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 0, 2, 2, 5, 5, 5 ]
 
    N = len(arr)
    K = 1
 
    length = longestSubarray(arr, N, K)
 
    if (length == 1):
        print("-1")
    else:
        print(length)
 
# This code is contributed by himanshu77


C#
// C# implementation to find the
// longest subarray consisting of
// only two values with difference K
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to return the length
// of the longest sub-array
static int longestSubarray(int []arr, int n,
                                      int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    HashSet s = new HashSet();
 
    for(i = 0; i < n - 1; i++)
    {
         
        // Store 1st element of
        // sub-array into set
        s.Add(arr[i]);
 
        for(j = i + 1; j < n; j++)
        {
             
            // Check absolute difference
            // between two elements
            if (Math.Abs(arr[i] - arr[j]) == 0 ||
                Math.Abs(arr[i] - arr[j]) == k)
            {
                 
                // If the new element is not
                // present in the set
                if (!s.Contains(arr[j]))
                {
                     
                    // If the set contains
                    // two elements
                    if (s.Count == 2)
                        break;
 
                    // Otherwise
                    else
                        s.Add(arr[j]);
                }
            }
            else
                break;
        }
        if (s.Count == 2)
        {
             
            // Update the maximum
            // length
            Max = Math.Max(Max, j - i);
 
            // Remove the set
            // elements
            s.Clear();
        }
        else
            s.Clear();
    }
    return Max;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = arr.Length;
    int K = 1;
    int length = longestSubarray(arr, N, K);
 
    if (length == 1)
        Console.Write(-1);
    else
        Console.Write(length);
}
}
 
// This code is contributed by Princi Singh


输出:
2

时间复杂度: O(N 2 * logN)
辅助空间: O(N)