📌  相关文章
📜  对于 [1, N] 中的每个值,找到该大小的所有子数组中存在的最小元素

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

对于 [1, N] 中的每个值,找到该大小的所有子数组中存在的最小元素

给定一个大小为N的数组A[] ,任务是找到从1 到 N的所有大小的所有子数组中存在的最小元素,其中数组中的所有元素都在1 到 N的范围内

例子:

朴素方法:解决问题的基本思想是找到[1, N]范围内所有大小的所有子数组。现在对于相同大小的所有子数组,找到这些子数组中的最小公共元素。请按照以下步骤解决问题:

  • i = 1 到 N迭代一个循环:
    • 创建每个可能的大小为i的子数组。
    • 计算所有子数组中每个元素的频率。
    • 检查任何元素的出现是否等于该大小的子数组的总数
    • 存储满足上述条件的第一个元素
  • 返回最小公共元素的结果数组。

下面是上述方法的实现。

C++
// C++ code for the above approach
 
#include 
using namespace std;
 
// Function to calculate
// the minimum element array
// from size 1 to N
vector Calculate_Min_array(vector& A,
                                int N)
{
    // Minimum elemnt array(ans)
    // Count array for every subsegment(cnt)
    // Total occurence array in all
    // subsegment of a given size(res)
    vector ans(N + 1, -1), cnt(N + 1, 0),
        res(N + 1, 0);
    for (int i = 1; i <= N; i++) {
 
        // Counting all the elements
        // for every subsegment of size i
        for (int j = 0; j < N - i + 1;
             j++) {
            for (int k = j; k < j + i;
                 k++) {
                cnt[A[k]]++;
            }
 
            // If count of element is
            // greater than 0 then
            // increment its occurence
            for (int k = 1; k <= N; k++) {
                if (cnt[k]) {
 
                    // If element is present
                    // increase its count
                    res[k]++;
                    cnt[k] = 0;
                }
            }
        }
 
        // When occurence of an element
        // is equal to total subsegment
        // of size i then we will get the
        // desired val for that subsegment
        for (int j = 1; j <= N; j++) {
            if (res[j] == (N - i + 1)) {
                ans[i] = j;
                break;
            }
            res[j] = 0;
        }
    }
 
    // Final array
    return ans;
}
 
// Print Function
void print(vector vec, int N)
{
    vector ans
        = Calculate_Min_array(vec, N);
 
    // Output
    for (int i = 1; i <= N; i++)
        cout << ans[i] << " ";
    cout << "\n";
}
 
// Driver code
int main()
{
    // Intialization of array
    vector A = { 1, 2, 3 };
    int N = 3;
 
    // Calling function
    print(A, N);
    return 0;
}


Java
// Java code for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to calculate
  // the minimum element array
  // from size 1 to N
  public static int[] Calculate_Min_array(int A[], int N)
  {
    // Minimum elemnt array(ans)
    // Count array for every subsegment(cnt)
    // Total occurence array in all
    // subsegment of a given size(res)
    int ans[] = new int[N + 1];
    int cnt[] = new int[N + 1];
    int res[] = new int[N + 1];
 
    for (int i = 0; i < N + 1; i++) {
      ans[i] = -1;
    }
    for (int i = 1; i <= N; i++) {
 
      // Counting all the elements
      // for every subsegment of size i
      for (int j = 0; j < N - i + 1; j++) {
        for (int k = j; k < j + i; k++) {
          cnt[A[k]]++;
        }
 
        // If count of element is
        // greater than 0 then
        // increment its occurence
        for (int k = 1; k <= N; k++) {
          if (cnt[k] != 0) {
 
            // If element is present
            // increase its count
            res[k]++;
            cnt[k] = 0;
          }
        }
      }
 
      // When occurence of an element
      // is equal to total subsegment
      // of size i then we will get the
      // desired val for that subsegment
      for (int j = 1; j <= N; j++) {
        if (res[j] == (N - i + 1)) {
          ans[i] = j;
          break;
        }
        res[j] = 0;
      }
    }
 
    // Final array
    return ans;
  }
 
  // Print Function
  public static void print(int vec[], int N)
  {
    int ans[] = Calculate_Min_array(vec, N);
 
    // Output
    for (int i = 1; i <= N; i++)
      System.out.print(ans[i] + " ");
    System.out.println();
  }
  public static void main(String[] args)
  {
    int A[] = { 1, 2, 3 };
    int N = 3;
 
    // Calling function
    print(A, N);
  }
}
 
// This code is contributed by Rohit Pradhan


Javascript


C++
// C++ code for the above approach:
 
#include 
using namespace std;
 
// Function to calculate
// the minimum element array
// from size 1 to N
vector Calculate_Min_array(vector& A,
                                int N)
{
 
    vector mx(N + 1, -1), ans(N + 1, -1);
    vector pos[N + 1];
 
    // Inserting the first position
    // of elements
    for (int i = 1; i <= N; i++) {
        pos[i].push_back(0);
    }
 
    // Inserting the diff position
    // of elements
    for (int i = 0; i < N; i++) {
        int x = A[i];
        pos[x].push_back(i + 1);
    }
 
    // Inserting the last position
    // of elements
    for (int i = 1; i <= N; i++) {
        pos[i].push_back(N + 1);
    }
 
    // Calculating max adjacent diff
    // of elements
    for (int i = 1; i <= N; i++) {
        for (int j = 0;
             j < pos[i].size() - 1; j++) {
            mx[i] = max(mx[i],
                        pos[i][j + 1]
                            - pos[i][j]);
        }
    }
 
    // Calculating ans for every subarray size
    for (int i = 1; i <= N; i++) {
        for (int j = mx[i]; j <= N; j++) {
 
            // If ans[j] is already present
            // move to next element
            if (ans[j] != -1)
                break;
 
            // Otherwise store the ans[j]=i
            ans[j] = i;
        }
    }
 
    // Final array
    return ans;
}
 
// Print Function
void print(vector A, int N)
{
    // Calculation Minmun element array
    // For Every subsegment length from
    // 1 to N
    vector ans
        = Calculate_Min_array(A, N);
 
    // Output
    for (int i = 1; i <= N; i++)
        cout << ans[i] << " ";
    cout << "\n";
}
 
// Driver code
int main()
{
    int N = 3;
 
    // Intialization of array
    vector A = { 1, 2, 3 };
    print(A, N);
    return 0;
}


输出
-1 2 1 

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

高效方法:高效解决问题的思路如下:

按照下面的步骤来实现上面的想法:

  • 为每个第 i 个元素创建一个数组(例如pos[i] )以存储数组中第 i 个元素的位置。
  • 然后计算每个元素的最大相邻差值。
  • i = 1 迭代到 N
    • j = 最大相邻差 2 iN开始另一个循环:
      • 如果未找到第 j 个大小的子数组的答案,则i是所有j个大小的子数组的最小公共元素,并继续获取更高的j值。
      • 否则,从循环中中断,因为所有更高的值也必须被填充
  • 返回结果数组。

下面是上述方法的实现:

C++

// C++ code for the above approach:
 
#include 
using namespace std;
 
// Function to calculate
// the minimum element array
// from size 1 to N
vector Calculate_Min_array(vector& A,
                                int N)
{
 
    vector mx(N + 1, -1), ans(N + 1, -1);
    vector pos[N + 1];
 
    // Inserting the first position
    // of elements
    for (int i = 1; i <= N; i++) {
        pos[i].push_back(0);
    }
 
    // Inserting the diff position
    // of elements
    for (int i = 0; i < N; i++) {
        int x = A[i];
        pos[x].push_back(i + 1);
    }
 
    // Inserting the last position
    // of elements
    for (int i = 1; i <= N; i++) {
        pos[i].push_back(N + 1);
    }
 
    // Calculating max adjacent diff
    // of elements
    for (int i = 1; i <= N; i++) {
        for (int j = 0;
             j < pos[i].size() - 1; j++) {
            mx[i] = max(mx[i],
                        pos[i][j + 1]
                            - pos[i][j]);
        }
    }
 
    // Calculating ans for every subarray size
    for (int i = 1; i <= N; i++) {
        for (int j = mx[i]; j <= N; j++) {
 
            // If ans[j] is already present
            // move to next element
            if (ans[j] != -1)
                break;
 
            // Otherwise store the ans[j]=i
            ans[j] = i;
        }
    }
 
    // Final array
    return ans;
}
 
// Print Function
void print(vector A, int N)
{
    // Calculation Minmun element array
    // For Every subsegment length from
    // 1 to N
    vector ans
        = Calculate_Min_array(A, N);
 
    // Output
    for (int i = 1; i <= N; i++)
        cout << ans[i] << " ";
    cout << "\n";
}
 
// Driver code
int main()
{
    int N = 3;
 
    // Intialization of array
    vector A = { 1, 2, 3 };
    print(A, N);
    return 0;
}
输出
-1 2 1 

时间复杂度:O(N) 因为虽然使用了嵌套循环,但最多填充了 N 个点,并且一个点最多被访问两次
辅助空间:O(N) 虽然使用了向量数组,但存储的总点数为 N