📌  相关文章
📜  每个大小为K的子数组中的最大唯一元素

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

给定一个数组和一个整数K。我们需要找到长度为K的每个分段的最大值,该分段中没有重复项。
例子:

Input : a[] = {1, 2, 2, 3, 3}, 
          K = 3.
Output : 1 3 2
For segment (1, 2, 2), Maximum = 1.
For segment (2, 2, 3), Maximum = 3.
For segment (2, 3, 3), Maximum = 2. 

Input : a[] = {3, 3, 3, 4, 4, 2},
          K = 4.
Output : 4 Nothing 3

一个简单的解决方案是运行两个循环。对于每个子数组,找到所有不同的元素并打印最大的唯一元素。
一个有效的解决方案是使用滑动窗口技术。我们在每个窗口中维护两个结构。
1)哈希表,用于存储当前窗口中所有元素的计数。
2)自平衡BST(使用C++ STL中的set和Java的TreeSet来实现)。这个想法是快速找到最大元素并更新最大元素。
我们处理第一个K-1元素,并将它们的计数存储在哈希表中。我们还将独特的元素存储在集合中。现在我们逐个处理每个窗口的最后一个元素。如果当前元素是唯一的,则将其添加到集合中。我们还增加了它的数量。处理完最后一个元素后,我们从集合中打印最大值。在开始下一次迭代之前,我们删除上一个窗口的第一个元素。

C++
// C++ code to calculate maximum unique
// element of every segment of array
#include 
using namespace std;
 
void find_max(int A[], int N, int K)
{
    // Storing counts of first K-1 elements
    // Also storing distinct elements.
    map Count;
    for (int i = 0; i < K - 1; i++)
        Count[A[i]]++;
    set Myset;
    for (auto x : Count)
        if (x.second == 1)
            Myset.insert(x.first);
 
    // Before every iteration of this loop,
    // we maintain that K-1 elements of current
    // window are processed.
    for (int i = K - 1; i < N; i++) {
 
        // Process K-th element of current window
        Count[A[i]]++;
        if (Count[A[i]] == 1)
            Myset.insert(A[i]);
        else
            Myset.erase(A[i]);
 
        // If there are no distinct
        // elements in current window
        if (Myset.size() == 0)
            printf("Nothing\n");
 
        // Set is ordered and last element
        // of set gives us maximum element.
        else
            printf("%d\n", *Myset.rbegin());
 
        // Remove first element of current
        // window before next iteration.
        int x = A[i - K + 1];
        Count[x]--;
        if (Count[x] == 1)
            Myset.insert(x);
        if (Count[x] == 0)
            Myset.erase(x);
    }
}
 
// Driver code
int main()
{
    int a[] = { 1, 2, 2, 3, 3 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 3;
    find_max(a, n, k);
    return 0;
}


Java
// Java code to calculate maximum unique
// element of every segment of array
import java.io.*;
import java.util.*;
class GFG {
 
    static void find_max(int[] A, int N, int K)
    {
        // Storing counts of first K-1 elements
        // Also storing distinct elements.
        HashMap Count = new HashMap<>();
        for (int i = 0; i < K - 1; i++)
            if (Count.containsKey(A[i]))
                Count.put(A[i], 1 + Count.get(A[i]));
            else
                Count.put(A[i], 1);
 
        TreeSet Myset = new TreeSet();
        for (Map.Entry x : Count.entrySet()) {
            if (Integer.parseInt(String.valueOf(x.getValue())) == 1)
                Myset.add(Integer.parseInt(String.valueOf(x.getKey())));
        }
 
        // Before every iteration of this loop,
        // we maintain that K-1 elements of current
        // window are processed.
        for (int i = K - 1; i < N; i++) {
 
            // Process K-th element of current window
            if (Count.containsKey(A[i]))
                Count.put(A[i], 1 + Count.get(A[i]));
            else
                Count.put(A[i], 1);
 
            if (Integer.parseInt(String.valueOf(Count.get(A[i]))) == 1)
                Myset.add(A[i]);
            else
                Myset.remove(A[i]);
 
            // If there are no distinct
            // elements in current window
            if (Myset.size() == 0)
                System.out.println("Nothing");
 
            // Set is ordered and last element
            // of set gives us maximum element.
            else
                System.out.println(Myset.last());
 
            // Remove first element of current
            // window before next iteration.
            int x = A[i - K + 1];
            Count.put(x, Count.get(x) - 1);
 
            if (Integer.parseInt(String.valueOf(Count.get(x))) == 1)
                Myset.add(x);
            if (Integer.parseInt(String.valueOf(Count.get(x))) == 0)
                Myset.remove(x);
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        int[] a = { 1, 2, 2, 3, 3 };
        int n = a.length;
        int k = 3;
        find_max(a, n, k);
    }
}
 
// This code is contributed by rachana soma


Python3
# Python3 code to calculate maximum unique
# element of every segment of array
def find_max(A, N, K):
     
    # Storing counts of first K-1 elements
    # Also storing distinct elements.
    Count = dict()
    for i in range(K - 1):
        Count[A[i]] = Count.get(A[i], 0) + 1
 
    Myset = dict()
    for x in Count:
        if (Count[x] == 1):
            Myset[x] = 1
 
    # Before every iteration of this loop,
    # we maintain that K-1 elements of current
    # window are processed.
    for i in range(K - 1, N):
 
        # Process K-th element of current window
        Count[A[i]] = Count.get(A[i], 0) + 1
 
        if (Count[A[i]] == 1):
            Myset[A[i]] = 1
        else:
            del Myset[A[i]]
 
        # If there are no distinct
        # elements in current window
        if (len(Myset) == 0):
            print("Nothing")
 
        # Set is ordered and last element
        # of set gives us maximum element.
        else:
            maxm = -10**9
            for i in Myset:
                maxm = max(i, maxm)
            print(maxm)
 
        # Remove first element of current
        # window before next iteration.
        x = A[i - K + 1]
        if x in Count.keys():
            Count[x] -= 1
            if (Count[x] == 1):
                Myset[x] = 1
            if (Count[x] == 0):
                del Myset[x]
 
# Driver code
a = [1, 2, 2, 3, 3 ]
n = len(a)
k = 3
find_max(a, n, k)
 
# This code is contributed
# by mohit kumar


C#
using System;
using System.Collections.Generic;
 
public class GFG
{
  static void find_max(int[] A, int N, int K)
  {
 
    // Storing counts of first K-1 elements
    // Also storing distinct elements.
    Dictionary count = new Dictionary(); 
    for (int i = 0; i < K - 1; i++)
    {
      if(count.ContainsKey(A[i]))
      {
        count[A[i]]++;
      }
      else
      {
        count.Add(A[i], 1);
      }
    }
    HashSet Myset = new HashSet();
    foreach(KeyValuePair x in count)
    {
      if(x.Value == 1)
      {
        Myset.Add(x.Key);
      }
    }
 
    // Before every iteration of this loop,
    // we maintain that K-1 elements of current
    // window are processed.
    for (int i = K - 1; i < N; i++)
    {
 
      // Process K-th element of current window
      if (count.ContainsKey(A[i]))
      {
        count[A[i]]++;
      }
      else
      {
        count.Add(A[i], 1);
      }
      if(count[A[i]] == 1)
      {
        Myset.Add(A[i]);
      }
      else
      {
        Myset.Remove(A[i]);
      }
 
      // If there are no distinct
      // elements in current window
      if (Myset.Count == 0)
        Console.Write("Nothing\n");
 
      // Set is ordered and last element
      // of set gives us maximum element.
      else
      {
        List myset = new List(Myset);
        Console.WriteLine(myset[myset.Count - 1]);
      }
 
      // Remove first element of current
      // window before next iteration.
      int x = A[i - K + 1];
      count[x]--;
      if(count[x] == 1)
      {
        Myset.Add(x);
      }
      if(count[x] == 0)
      {
        Myset.Remove(x);
      }
    }
 
  }
 
  // Driver code
  static public void Main ()
  {
    int[] a = { 1, 2, 2, 3, 3 };
    int n=a.Length;
    int k = 3;
    find_max(a, n, k);
  }
}
 
// This code is contributed by rag2127


输出:

1
3
2

时间复杂度: O(N Log K)