给定N个整数的数组arr []和以下两种类型的{X,Y}形式的Q个查询:
- 如果X = 1 ,则将给定数组向左旋转Y个位置。
- 如果X = 2 ,则在数组的当前状态下打印长度为Y的最大和子数组。
例子:
Input: N = 5, arr[] = {1, 2, 3, 4, 5}, Q = 2, Query[][] = {{1, 2}, {2, 3}}
Output:
Query 1: 3 4 5 1 2
Query 2: 12
Explanation:
Query 1: Shift array to the left 2 times: {1, 2, 3, 4, 5} -> {2, 3, 4, 5, 1} -> {3, 4, 5, 1, 2}
Query 2: Maximum sum subarray of length 3 is {3, 4, 5} and the sum is 12
Input: N = 5, arr[] = {3, 4, 5, 1, 2}, Q = 3, Query[][] = {{1, 3}, {1, 1}, {2, 4}}
Output:
Query 1: 1 2 3 4 5
Query 2: 2 3 4 5 1
Query 3: 14
Explanation:
Query 1: Shift array to the left 3 times: {3, 4, 5, 1, 2} -> {4, 5, 1, 2, 3} -> {5, 1, 2, 3, 4} -> {1, 2, 3, 4, 5}
Query 2: Shift array to the left 1 time: {1, 2, 3, 4, 5} -> {2, 3, 4, 5, 1}
Query 3: Maximum sum subarray of length 4 is {2, 3, 4, 5} and sum is 14
天真的方法:最简单的方法是通过将元素逐一移位直到距离Y来旋转数组,以用于查询类型为1的查询,并生成长度为Y的所有子数组的和,如果查询的类型为2 ,则打印最大和。
时间复杂度: O(Q * N * Y)
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是使用杂耍算法进行阵列旋转,并使用滑动窗口技术找到长度为Y的最大和子阵列。请按照以下步骤解决问题:
- 如果X = 1 ,则使用杂耍算法将数组旋转Y。
- 否则,如果X = 2 ,则使用滑动窗口技术找到长度Y的最大和子数组。
- 如果查询X为1,则打印数组。
- 否则,打印大小为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
3 4 5 1 2
12
1 2 3 4 5
2 3 4 5 1
14
时间复杂度: O(Q * N),其中Q是查询数, N是给定数组的大小。
辅助空间: O(N)