给定一个由N对组成的数组arr [] ,每个对都由一个字符串和一个与该字符串对应的整数组成。任务是找到最大绝对和子数组并打印与子数组元素相对应的字符串。
例子:
Input: arr[] = {(“geeks”, 4), (“for”, -3), (“geeks”, 2), (“tutorial”, 3), (“program”, -4)}
Output: geeks for geeks tutorial
Explanation: The maximum absolute sum subarray is {arr[0], .. arr[3]}, having sum 6. Therefore, corresponding strings between these values are “geeks”, “for”, “geeks” and “tutorial”.
Input: arr[]= {(“practice”, -7), (“makes”, 2 ), (“men perfect”, 5)}
Output: practice
Explanation: The maximum absolute sum subarray is {arr[0]}, having sum 7. Therefore, corresponding string is “practice”.
天真的方法:最简单的方法是生成所有可能的子数组,找到最大的总和子数组。然后,打印与该子数组相对应的字符串。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:最佳方法是使用经过修改的Kadane算法,以便它可以处理负值并在绝对最小值和绝对最大值之间选择最大值。
请按照以下步骤解决问题:
- 初始化 变量res = 0 ,以存储最终答案,而start = 0 , end = 0,以存储所需子数组的开始和结束索引。
- 初始化另外两个变量posPrefix和negPrefix ,以存储先前的正前缀值和负前缀值。
- 遍历数组arr []并执行以下操作
- 如果当前元素为负,并且如果arr [i] + negPrefix> res的值,则更新res的值,开始索引和结束索引。
- 如果当前元素为正,并且arr [i] + posPrefix> res的值,则更新res的值,开始索引和结束索引。
- 检查是否将当前元素添加到negPrefix使其大于或等于0 ,然后更新start = i + 1并设置negPrefix = 0,否则,将当前值添加到negPrefix 。
- 检查将当前元素添加到posPrefix是否使其小于或等于0 ,然后更新start = i + 1并设置posPrefix = 0,否则,将当前值添加到posPrefix 。
- 最后,遍历[start,end]范围内的数组并打印相应的字符串。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to print strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
void maximumAbsSum(pair* arr,
int N)
{
int start = 0, end = 0, res = 0,
negIndex = 0, posIndex = 0,
negPrefix = 0, posPrefix = 0;
// Traverse the array
for (int i = 0; i < N; i++) {
if (arr[i].second < 0) {
// If adding current element
// to negative
// prefix makes it > res
// then update the values
if (res < abs(arr[i].second
+ negPrefix)) {
res = abs(arr[i].second
+ negPrefix);
start = negIndex;
end = i;
}
}
else {
// If adding current element to
// positive prefix exceeds res
if (res < abs(arr[i].second
+ posPrefix)) {
res = abs(arr[i].second
+ posPrefix);
start = posIndex;
end = i;
}
}
// Since negPrefix > 0, there is
// no benefit in adding it to a
// negative value
if (negPrefix + arr[i].second > 0) {
negPrefix = 0;
negIndex = i + 1;
}
// Since negative + negative
// generates a larger negative value
else {
negPrefix += arr[i].second;
}
// Sicne positive + positive
// generates a larger positive number
if (posPrefix + arr[i].second >= 0) {
posPrefix += arr[i].second;
}
// Since pos_prefix < 0, there is
// no benefit in adding it to
// a positive value
else {
posPrefix = 0;
posIndex = i + 1;
}
}
// Print the corresponding strings
for (int i = start; i <= end; i++) {
cout << arr[i].first << " ";
}
}
// Driver Code
int main()
{
// Given array
pair arr[] = { { "geeks", 4 },
{ "for", -3 },
{ "geeks", 2 },
{ "tutorial", 3 },
{ "program", -4 } };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
// Function call to print
// string corresponding to
// maximum absolute subarray sum
maximumAbsSum(arr, N);
}
Java
// Java program for the above approach
class GFG
{
static class pair
{
E first;
R second;
public pair(E first, R second)
{
this.first = first;
this.second = second;
}
}
// Function to print Strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
static void maximumAbsSum(pair []arr,
int N)
{
int start = 0, end = 0, res = 0,
negIndex = 0, posIndex = 0,
negPrefix = 0, posPrefix = 0;
// Traverse the array
for (int i = 0; i < N; i++)
{
if (arr[i].second < 0)
{
// If adding current element
// to negative
// prefix makes it > res
// then update the values
if (res < Math.abs(arr[i].second
+ negPrefix)) {
res = Math.abs(arr[i].second
+ negPrefix);
start = negIndex;
end = i;
}
}
else
{
// If adding current element to
// positive prefix exceeds res
if (res < Math.abs(arr[i].second
+ posPrefix)) {
res = Math.abs(arr[i].second
+ posPrefix);
start = posIndex;
end = i;
}
}
// Since negPrefix > 0, there is
// no benefit in adding it to a
// negative value
if (negPrefix + arr[i].second > 0) {
negPrefix = 0;
negIndex = i + 1;
}
// Since negative + negative
// generates a larger negative value
else {
negPrefix += arr[i].second;
}
// Sicne positive + positive
// generates a larger positive number
if (posPrefix + arr[i].second >= 0) {
posPrefix += arr[i].second;
}
// Since pos_prefix < 0, there is
// no benefit in adding it to
// a positive value
else {
posPrefix = 0;
posIndex = i + 1;
}
}
// Print the corresponding Strings
for (int i = start; i <= end; i++) {
System.out.print(arr[i].first+ " ");
}
}
// Driver Code
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
// Given array
@SuppressWarnings("rawtypes")
pair arr[] = { new pair( "geeks", 4 ),
new pair( "for", -3 ),
new pair( "geeks", 2 ),
new pair( "tutorial", 3 ),
new pair( "program", -4 ) };
// Size of the array
int N = arr.length;
// Function call to print
// String corresponding to
// maximum absolute subarray sum
maximumAbsSum(arr, N);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to print strings corresponding
# to the elements present in the subarray
# with maximum absolute sum
def maximumAbsSum(arr, N):
start, end, res = 0, 0, 0
negIndex, posIndex = 0, 0
negPrefix, posPrefix = 0, 0
# Traverse the array
for i in range(N):
if (arr[i][1] < 0):
# If adding current element
# to negative
# prefix makes it > res
# then update the values
if (res < abs(arr[i][1] + negPrefix)):
res = abs(arr[i][1] + negPrefix)
start = negIndex
end = i
else:
# If adding current element to
# positive prefix exceeds res
if (res < abs(arr[i][1] + posPrefix)):
res = abs(arr[i][1] + posPrefix)
start = posIndex
end = i
# Since negPrefix > 0, there is
# no benefit in adding it to a
# negative value
if (negPrefix + arr[i][1] > 0):
negPrefix = 0
negIndex = i + 1
# Since negative + negative
# generates a larger negative value
else:
negPrefix += arr[i][1]
# Sicne positive + positive
# generates a larger positive number
if (posPrefix + arr[i][1] >= 0):
posPrefix += arr[i][1]
# Since pos_prefix < 0, there is
# no benefit in adding it to
# a positive value
else:
posPrefix = 0
posIndex = i + 1
# Print the corresponding strings
for i in range(start, end + 1):
print(arr[i][0], end = " ")
# Driver Code
if __name__ == '__main__':
# Given array
arr = [ [ "geeks", 4 ],
[ "for", -3 ],
[ "geeks", 2 ],
[ "tutorial", 3 ],
[ "program", -4 ] ]
# Size of the array
N = len(arr)
# Function call to print
# string corresponding to
# maximum absolute subarray sum
maximumAbsSum(arr, N)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG
{
public class pair
{
public string first;
public int second;
public pair(string first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to print Strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
static void maximumAbsSum(pair []arr,
int N)
{
int start = 0, end = 0, res = 0,
negIndex = 0, posIndex = 0,
negPrefix = 0, posPrefix = 0;
// Traverse the array
for (int i = 0; i < N; i++)
{
if (arr[i].second < 0)
{
// If adding current element
// to negative
// prefix makes it > res
// then update the values
if (res < Math.Abs(arr[i].second
+ negPrefix)) {
res = Math.Abs(arr[i].second
+ negPrefix);
start = negIndex;
end = i;
}
}
else
{
// If adding current element to
// positive prefix exceeds res
if (res < Math.Abs(arr[i].second
+ posPrefix)) {
res = Math.Abs(arr[i].second
+ posPrefix);
start = posIndex;
end = i;
}
}
// Since negPrefix > 0, there is
// no benefit in adding it to a
// negative value
if (negPrefix + arr[i].second > 0) {
negPrefix = 0;
negIndex = i + 1;
}
// Since negative + negative
// generates a larger negative value
else {
negPrefix += arr[i].second;
}
// Sicne positive + positive
// generates a larger positive number
if (posPrefix + arr[i].second >= 0) {
posPrefix += arr[i].second;
}
// Since pos_prefix < 0, there is
// no benefit in adding it to
// a positive value
else {
posPrefix = 0;
posIndex = i + 1;
}
}
// Print the corresponding Strings
for (int i = start; i <= end; i++) {
Console.Write(arr[i].first+ " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given array
pair []arr = { new pair( "geeks", 4 ),
new pair( "for", -3 ),
new pair( "geeks", 2 ),
new pair( "tutorial", 3 ),
new pair( "program", -4 ) };
// Size of the array
int N = arr.Length;
// Function call to print
// String corresponding to
// maximum absolute subarray sum
maximumAbsSum(arr, N);
}
}
// This code is contributed by Rajput-Ji
geeks for geeks tutorial
时间复杂度: O(N)
辅助空间: O(1)