📜  查找前缀的最大长度 |第 2 组

📅  最后修改于: 2022-05-13 01:57:51.188000             🧑  作者: Mango

查找前缀的最大长度 |第 2 组

给定一个包含N个整数的数组arr[] ,任务是找到数组的最大前缀长度,使得从前缀中删除一个元素将使其余前缀元素的频率相同。

例子:

本文的第 1 组已经讨论了基于散列和排序的方法。

方法:这个想法是使用两个 Map 来跟踪元素的频率,并使用以下四个条件来检查有效的前缀。

  1. 前缀的所有元素的频率都等于1。
  2. 全部 前缀窗口中的元素是相同的。
  3. 前缀中的元素只存在两个不同的频率,它们之间的差等于1 ,值较大的频率计数为1。
  4. 存在频率为1的单个元素,除了所有元素具有相同的频率。

请按照以下步骤解决问题:

  • 初始化两个 Map,分别是mp1mp2来存储前缀中元素的频率,并分别存储元素的频率。
  • 此外,初始化一个变量说ans0以存储前缀的最大长度。
  • 使用变量i遍历范围[0, N-1]并执行以下步骤:
    • 如果arr[i]的计数不等于0 ,则从映射mp2中减少该频率的计数,如果它变为0 ,则从映射mp2 中删除该值。
    • 将映射mp1arr[i]的计数加1 ,然后将arr[i]的新频率计数,即 Map mp2中的mp1[arr[i]]1。
    • 如果当前元素的计数等于其前缀长度,即(i+1 ) 或每个元素在前缀中出现一次,则将ans的值更新为max(ans, i+1)
    • 现在,如果mp2的大小等于2则执行以下步骤,
      • 将数组元素的频率(即映射mp2的键)分别存储在变量中,例如freq1freq2
      • freq1freq2的频率计数存储在变量count1count2中。
      • 检查freq2freq1之间的差是否等于1并且count2的值是否等于1 ,然后将ans更新为max(ans, i+1)
      • 否则,如果freq1freq2之间的差等于1 ,并且count1的值等于1 ,则将ans更新为max(ans, i+1)
      • 否则,如果freq2count2等于1freq1count1等于1 ,则将ans更新为max(ans, i+1)
  • 最后,完成上述步骤后,打印ans的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the maximum
// length of the required prefix
int maxPrefixLen(int arr[], int N)
{
 
    // Stores the frequency of
    // elements
    unordered_map a, b;
 
    // Stores the maximum length
    // of the prefix satisfying
    // the conditions
    int ans = 1;
 
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
 
        // Stores the count of
        // current element
        int curr = a[arr[i]];
 
        // If curr is not
        // equal to 0
        if (curr != 0) {
 
            // Decrement b[curr]
            // by 1
            b[curr]--;
 
            // If b[curr] is 0
            if (b[curr] == 0) {
                // Remove b[curr]
                // from the b
                b.erase(curr);
            }
        }
 
        // Update
        a[arr[i]]++;
        b[curr + 1]++;
 
        // If all elements in the
        // prefix are same or if
        // all elements have frequency
        // 1
        if (a[arr[i]] == i + 1
            or (b.find(1) != b.end() and b[1] == i + 1)) {
            // Update the value of ans
            ans = max(ans, i + 1);
        }
 
        // Else if the size of b
        // is 2
        else if (b.size() == 2) {
 
            auto p = b.begin();
            auto q = p;
 
            // Increment q by 1
            q++;
 
            int freq1 = p->first;
            int freq2 = q->first;
 
            int count1 = p->second;
            int count2 = q->second;
 
            // If difference between
            // freq2 and freq1 is
            // equal to 1 and if
            // count2 is equal to 1
            if (freq2 - freq1 == 1 and count2 == 1) {
                // Update the value
                // of ans
                ans = max(ans, i + 1);
            }
 
            // If difference between
            // freq1 and freq2 is
            // equal to 1 and if
            // count1 is equal to 1
            else if (freq1 - freq2 == 1 and count1 == 1) {
                // Update the value
                // of ans
                ans = max(ans, i + 1);
            }
            // If freq2 and count2 is 1
            // or freq1 and count1 is 1
            if ((freq2 == 1 and count2 == 1)
                or (freq1 == 1 and count1 == 1)) {
                // Update the value of
                // ans
                ans = max(ans, i + 1);
            }
        }
    }
 
    // Return ans
    return ans;
}
 
// Driver Code
int main()
{
 
    int arr[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << maxPrefixLen(arr, N);
}


Java
// Java program for the above approach
import java.util.HashMap;
class GFG {
 
    // Function to find the maximum
    // length of the required prefix
    public static int maxPrefixLen(int arr[], int N)
    {
 
        // Stores the frequency of
        // elements
        HashMap a = new HashMap();
        HashMap b = new HashMap();
 
        // Stores the maximum length
        // of the prefix satisfying
        // the conditions
        int ans = 1;
 
        // Traverse the array arr[]
        for (int i = 0; i < N; i++) {
 
            // Stores the count of
            // current element
            int curr = !a.containsKey(arr[i]) ? 0 : a.get(arr[i]);
 
            // If curr is not
            // equal to 0
            if (curr != 0) {
 
                // Decrement b[curr]
                // by 1
                b.put(curr, b.get(curr) - 1);
 
                // If b[curr] is 0
                if (b.get(curr) == 0)
                {
                   
                    // Remove b[curr]
                    // from the b
                    b.remove(curr);
                }
            }
 
            // Update
            if (a.containsKey(arr[i])) {
                a.put(arr[i], a.get(arr[i]) + 1);
            } else {
                a.put(arr[i], 1);
            }
 
            if (b.containsKey(curr + 1)) {
                b.put(curr + 1, b.get(curr + 1) + 1);
            } else {
                b.put(curr + 1, 1);
            }
 
            // If all elements in the
            // prefix are same or if
            // all elements have frequency
            // 1
            if (a.get(arr[i]) == i + 1 || (b.containsKey(1) && b.get(1) == i + 1))
            {
               
                // Update the value of ans
                ans = Math.max(ans, i + 1);
            }
 
            else if (b.size() == 2) {
 
                int p = b.keySet().toArray()[0].hashCode();
                int q = b.keySet().toArray()[1].hashCode();
 
                // Increment q by 1
 
                int freq1 = p;
                int freq2 = q;
 
                int count1 = b.get(p);
                int count2 = b.get(q);
 
                // If difference between
                // freq2 and freq1 is
                // equal to 1 and if
                // count2 is equal to 1
                if ((freq2 - freq1) == 1 && count2 == 1)
                {
                   
                    // Update the value
                    // of ans
                    ans = Math.max(ans, i + 1);
                }
 
                // If difference between
                // freq1 and freq2 is
                // equal to 1 and if
                // count1 is equal to 1
                else if (freq1 - freq2 == 1 && count1 == 1)
                {
                   
                    // Update the value
                    // of ans
                    ans = Math.max(ans, i + 1);
                }
                // If freq2 and count2 is 1
                // or freq1 and count1 is 1
                if ((freq2 == 1 && count2 == 1) || (freq1 == 1 && count1 == 1))
                {
                   
                    // Update the value of
                    // ans
                    ans = Math.max(ans, i + 1);
                }
            }
        }
       
        // Return ans
        return ans;
    }
 
    // Driver Code
    public static void main(String args[]) {
 
        int arr[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5 };
        int N = arr.length;
 
        System.out.println(maxPrefixLen(arr, N));
    }
}
 
// This code is contributed by gfgking.


Python3
# Python3 program for the above approach
 
# Function to find the maximum
# length of the required prefix
def maxPrefixLen(arr, N):
 
    # Stores the frequency of
    # elements
    a, b = {}, {}
 
    # Stores the maximum length
    # of the prefix satisfying
    # the conditions
    ans = 1
 
    # Traverse the array arr[]
    for i in range(N):
         
        # Stores the count of
        # current element
        curr = 0 if (arr[i] not in a) else a[arr[i]]
 
        # If curr is not
        # equal to 0
        if (curr != 0):
             
            # Decrement b[curr]
            # by 1
            b[curr] -= 1
             
            # If b[curr] is 0
            if (b[curr] == 0):
                 
                # Remove b[curr]
                # from the b
                del b[curr]
 
        # Update
        a[arr[i]] = a.get(arr[i], 0) + 1
        b[curr + 1] = b.get(curr + 1, 0) + 1
  
        # If all elements in the
        # prefix are same or if
        # all elements have frequency
        # 1
        if (a[arr[i]] == i + 1 or
           (1 in b) and b[1] == i + 1):
                
            # Update the value of ans
            ans = max(ans, i + 1)
 
        # Else if the size of b
        # is 2
        elif (len(b) == 2):
            p = list(b.keys())[0]
            q = list(b.keys())[1]
 
            freq1 = p
            freq2 = q
 
            count1 = b[p]
            count2 = b[q]
             
            # If difference between
            # freq2 and freq1 is
            # equal to 1 and if
            # count2 is equal to 1
            if (freq2 - freq1 == 1 and count2 == 1):
                 
                # Update the value
                # of ans
                ans = max(ans, i + 1)
 
            # If difference between
            # freq1 and freq2 is
            # equal to 1 and if
            # count1 is equal to 1
            elif (freq1 - freq2 == 1 and count1 == 1):
                 
                # Update the value
                # of ans
                ans = max(ans, i + 1)
                 
            # If freq2 and count2 is 1
            # or freq1 and count1 is 1
            if ((freq2 == 1 and count2 == 1) or
                (freq1 == 1 and count1 == 1)):
                     
                # Update the value of
                # ans
                ans = max(ans, i + 1)
 
    # Return ans
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 1, 1, 2, 2, 2, 3,
            3, 3, 4, 4, 4, 5 ]
    N = len(arr)
 
    print(maxPrefixLen(arr, N))
 
# This code is contributed by mohit kumar 29


Javascript


输出:
13

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