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

📅  最后修改于: 2021-09-07 02:07:07             🧑  作者: Mango

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

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

例子:

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

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

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

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the maximum
// sum of length k
int MaxSum(vector 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
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
vector RotateArr(vector 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
void performQuery(vector& arr,
                  int Q[][2], int q)
{
 
    int N = (int)arr.size();
 
    // 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 (auto t : arr) {
                cout << t << " ";
            }
            cout << "\n";
        }
 
        // If query of type X = 2
        else {
            cout << MaxSum(arr, N, Q[i][1])
                 << "\n";
        }
    }
}
 
// Driver Code
int main()
{
    // Given array arr[]
    vector arr = { 1, 2, 3, 4, 5 };
 
    int q = 5;
 
    // Given Queries
    int Q[][2] = { { 1, 2 }, { 2, 3 },
                   { 1, 3 }, { 1, 1 },
                   { 2, 4 }
    };
 
    // Function Call
    performQuery(arr, Q, q);
 
    return 0;
}


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("\n");
    }
 
    // If query of type X = 2
    else
    {
      System.out.print(MaxSum(arr, N,
                              Q[i][1]) + "\n");
    }
  }
}
 
// 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


Python3
# Python3 program for the above approach
 
# Function to calculate the maximum
# sum of length k
def MaxSum(arr, n, k):
     
    i, max_sum = 0, 0
    sum = 0
 
    # Calculating the max sum for
    # the first k elements
    while i < k:
        sum += arr[i]
        i += 1
         
    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 += 1
 
    # Return maximum sum
    return max_sum
 
# Function to calculate gcd of the
# two numbers n1 and n2
def gcd(n1, 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
def RotateArr(arr, n, d):
     
    # For handling k >= N
    i = 0
    j = 0
    d = d % n
 
    # Dividing the array into
    # number of sets
    no_of_sets = gcd(d, n)
 
    for i in range(no_of_sets):
        temp = arr[i]
        j = i
 
        # Rotate the array by Y
        while (True):
            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
def performQuery(arr, Q, q):
 
    N = len(arr)
 
    # Traverse each query
    for i in range(q):
 
        # If query of type X = 1
        if (Q[i][0] == 1):
            arr = RotateArr(arr, N, Q[i][1])
 
            # Print the array
            for t in arr:
                print(t, end = " ")
                 
            print()
 
        # If query of type X = 2
        else:
            print(MaxSum(arr, N, Q[i][1]))
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 1, 2, 3, 4, 5 ]
 
    q = 5
 
    # Given Queries
    Q = [ [ 1, 2 ], [ 2, 3 ],
          [ 1, 3 ], [ 1, 1 ],
          [ 2, 4 ] ]
 
    # Function call
    performQuery(arr, Q, q)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
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 = 0; t < arr.Length; t++)
            {
                Console.Write(arr[t] + " ");
            }
            Console.WriteLine();
        }
     
        // If query of type X = 2
        else
        {
            Console.WriteLine(MaxSum(arr, N,
                                     Q[i, 1]));
        }
    }
}
 
// Driver code
static void Main()
{
     
    // 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 divyeshrabadiya07


Javascript


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

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live