📌  相关文章
📜  用于查询的Java程序在旋转数组中查找给定长度的最大和连续子数组

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

用于查询的Java程序在旋转数组中查找给定长度的最大和连续子数组

给定一个包含N个整数的数组arr[]和以下两种类型的{X, Y}形式的Q个查询:

  • 如果X = 1 ,将给定数组向左旋转Y个位置。
  • 如果X = 2 ,则在数组的当前状态下打印长度为Y的最大和子数组。

例子:

天真的方法:最简单的方法是通过将元素一个一个移动到距离Y来旋转数组,查询类型为 1 ,并生成长度为 Y 的所有子数组的总和,如果查询类型为 2 ,则打印最大总和.
时间复杂度: O(Q*N*Y)
辅助空间: O(N)

有效方法:为了优化上述方法,我们的想法是使用杂耍算法进行数组旋转并找到长度为Y的最大和子数组,使用滑动窗口技术。请按照以下步骤解决问题:

  1. 如果X = 1 ,使用杂耍算法将数组旋转Y
  2. 否则,如果X = 2 ,则使用滑动窗口技术找到长度为 Y 的最大和子数组。
  3. 如果查询X1 ,则打印数组。
  4. 否则,打印大小为Y的最大和子数组。

下面是上述方法的实现:

Java
// Java program for 
// the above approach
class GFG{
  
// Function to calculate the maximum
// sum of length k
static int MaxSum(int []arr, 
                  int n, int k)
{
  int i, max_sum = 0, sum = 0;
  
  // Calculating the max sum for
  // the first k elements
  for (i = 0; i < k; i++) 
  {
    sum += arr[i];
  }
  max_sum = sum;
  
  // Find subarray with maximum sum
  while (i < n) 
  {
    // Update the sum
    sum = sum - arr[i - k] +
                arr[i];
    if (max_sum < sum) 
    {
      max_sum = sum;
    }
    i++;
  }
  
  // Return maximum sum
  return max_sum;
}
  
// Function to calculate gcd 
//  of the two numbers n1 and n2
static int gcd(int n1, int n2)
{
  // Base Case
  if (n2 == 0) 
  {
    return n1;
  }
  
  // Recursively find the GCD
  else 
  {
    return gcd(n2, n1 % n2);
  }
}
  
// Function to rotate the array by Y
static int []RotateArr(int []arr,
                       int n, int d)
{
  // For handling k >= N
  int i = 0, j = 0;
  d = d % n;
  
  // Dividing the array into
  // number of sets
  int no_of_sets = gcd(d, n);
  
  for (i = 0; i < no_of_sets; i++) 
  {
    int temp = arr[i];
    j = i;
  
    // Rotate the array by Y
    while (true) 
    {
      int k = j + d;
  
      if (k >= n)
        k = k - n;
  
      if (k == i)
        break;
  
      arr[j] = arr[k];
      j = k;
    }
  
    // Update arr[j]
    arr[j] = temp;
  }
  
  // Return the rotated array
  return arr;
}
  
// Function that performs the queries
// on the given array
static void performQuery(int []arr,
                         int Q[][], int q)
{
  int N = arr.length;
  
  // Traverse each query
  for (int i = 0; i < q; i++) 
  {
    // If query of type X = 1
    if (Q[i][0] == 1) 
    {
      arr = RotateArr(arr, N,
                      Q[i][1]);
  
      // Print the array
      for (int t : arr) 
      {
        System.out.print(t + " ");
      }
      System.out.print("
");
    }
  
    // If query of type X = 2
    else 
    {
      System.out.print(MaxSum(arr, N, 
                              Q[i][1]) + "
");
    }
  }
}
  
// Driver Code
public static void main(String[] args)
{
  // Given array arr[]
  int []arr = {1, 2, 3, 4, 5};
  
  int q = 5;
  
  // Given Queries
  int Q[][] = {{1, 2}, {2, 3}, 
               {1, 3}, {1, 1}, 
               {2, 4}};
  
  // Function Call
  performQuery(arr, Q, q);
}
}
  
// This code is contributed by Rajput-Ji


输出:
3 4 5 1 2 
12
1 2 3 4 5 
2 3 4 5 1 
14

时间复杂度: O(Q*N),其中 Q 是查询数N 是给定数组的大小。
辅助空间: O(N)

请参阅有关查询的完整文章以在旋转数组中查找给定长度的最大和连续子数组以获取更多详细信息!