用最多 K 个下一个和 K 个前一个元素替换每个数组元素
给定一个数组arr ,任务是将每个数组元素替换为 K 下一个和 K 前一个元素中的最大值。
例子:
Input: arr[] = {12, 5, 3, 9, 21, 36, 17}, K=2
Output: 5 12 21 36 36 21 36
Input: arr[] = { 13, 21, 19}, K=1
Output: 21, 19, 21
天真的方法:按照以下步骤解决此问题:
- 遍历数组从i=0到i
并且对于每个元素: - 从j=iK到j<=i+K运行另一个循环,并将arr[i]更改为 K next 和 K previous 元素的最大值。
- 在上述循环结束后打印数组。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#include
#include
using namespace std;
// Function to update the array
// arr[i] = maximum of prev K and next K elements.
void updateArray(int arr[], int N, int K)
{
int start, end;
for (int i = 0; i < N; i++) {
int mx = INT_MIN;
// Start limit is max(i-K, 0)
start = max(i - K, 0);
// End limit in min(i+K, N-1)
end = min(i + K, N - 1);
for (int j = start; j <= end; j++) {
// Skipping the current element
if (j == i) {
continue;
}
mx = max(arr[j], mx);
}
cout << mx << ' ';
}
}
// Driver Code
int main()
{
int arr[] = { 12, 5, 3, 9, 21, 36, 17 };
int N = sizeof(arr) / sizeof(arr[0]);
int K = 2;
updateArray(arr, N, K);
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to update the array arr[i] = maximum
// of prev K and next K elements.
static void updateArray(int arr[], int N, int K)
{
int start, end;
for(int i = 0; i < N; i++)
{
int mx = Integer.MIN_VALUE;
// Start limit is max(i-K, 0)
start = Math.max(i - K, 0);
// End limit in min(i+K, N-1)
end = Math.min(i + K, N - 1);
for(int j = start; j <= end; j++)
{
// Skipping the current element
if (j == i)
{
continue;
}
mx = Math.max(arr[j], mx);
}
System.out.print(mx + " ");
}
}
// Driver Code
public static void main(String args[])
{
int arr[] = { 12, 5, 3, 9, 21, 36, 17 };
int N = arr.length;
int K = 2;
updateArray(arr, N, K);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# python3 program for the above approach
INT_MIN = -2147483648
# Function to update the array
# arr[i] = maximum of prev K and next K elements.
def updateArray(arr, N, K):
for i in range(0, N):
mx = INT_MIN
# Start limit is max(i-K, 0)
start = max(i - K, 0)
# End limit in min(i+K, N-1)
end = min(i + K, N - 1)
for j in range(start, end + 1):
# Skipping the current element
if (j == i):
continue
mx = max(arr[j], mx)
print(mx, end=" ")
# Driver Code
if __name__ == "__main__":
arr = [12, 5, 3, 9, 21, 36, 17]
N = len(arr)
K = 2
updateArray(arr, N, K)
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
class GFG
{
// Function to update the array arr[i] = maximum
// of prev K and next K elements.
static void updateArray(int[] arr, int N, int K)
{
int start, end;
for (int i = 0; i < N; i++)
{
int mx = int.MinValue;
// Start limit is max(i-K, 0)
start = Math.Max(i - K, 0);
// End limit in min(i+K, N-1)
end = Math.Min(i + K, N - 1);
for (int j = start; j <= end; j++)
{
// Skipping the current element
if (j == i)
{
continue;
}
mx = Math.Max(arr[j], mx);
}
Console.Write(mx + " ");
}
}
// Driver Code
public static void Main()
{
int[] arr = { 12, 5, 3, 9, 21, 36, 17 };
int N = arr.Length;
int K = 2;
updateArray(arr, N, K);
}
}
// This code is contributed by Saurabh Jaiswal
Javascript
C++
// C++ code for the above approach
#define MAXN 500001
#include
using namespace std;
// Function to build the tree
void buildTree(vector& arr,
vector& tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s,
mid, 2 * index + 1);
buildTree(arr, tree, mid + 1,
e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index]
= max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
int query(vector& tree, int s,
int e, int index, int l,
int r)
{
if (l > e or r < s) {
return INT_MIN;
}
if (l <= s and r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid,
2 * index + 1, l, r);
int right
= query(tree, mid + 1, e,
2 * index + 2, l, r);
return max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
void updateArray(vector& arr, int K)
{
// To store the segment tree
vector tree(MAXN);
int N = arr.size();
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i) {
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
cout << query(tree, 0, N - 1, 0, 1,
min(i + K, N - 1))
<< ' ';
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
cout << query(tree, 0, N - 1,
0, max(0, i - K),
N - 2);
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1,
0, max(i - K, 0),
i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0,
N - 1, 0, i + 1,
min(i + K, N - 1));
cout << max(left, right) << ' ';
}
}
// Driver Code
int main()
{
vector arr = { 12, 5, 3, 9,
21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
Java
// Java code for the above approach
import java.io.*;
class GFG {
static int MAXN = 500001;
// Function to build the tree
static void buildTree(int[] arr, int[] tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s, mid, 2 * index + 1);
buildTree(arr, tree, mid + 1, e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index] = Math.max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
static int query(int[] tree, int s, int e, int index,
int l, int r)
{
if (l > e || r < s) {
return Integer.MIN_VALUE;
}
if (l <= s && r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid, 2 * index + 1, l, r);
int right
= query(tree, mid + 1, e, 2 * index + 2, l, r);
return Math.max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
static void updateArray(int[] arr, int K)
{
// To store the segment tree
int[] tree = new int[MAXN];
int N = arr.length;
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i)
{
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
System.out.print(query(tree, 0, N - 1, 0, 1,
Math.min(i + K, N - 1))
+ " ");
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
System.out.println(query(tree, 0, N - 1, 0,
Math.max(0, i - K),
N - 2));
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1, 0,
Math.max(i - K, 0), i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0, N - 1, 0, i + 1,
Math.min(i + K, N - 1));
System.out.print(Math.max(left, right) + " ");
}
}
// Driver Code
public static void main (String[] args)
{
int[] arr = { 12, 5, 3, 9, 21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
}
// This code is contributed by Shubham Singh.
Python3
# Python code for the above approach
import sys
MAXN = 500001
# Function to build the tree
def buildTree(arr, tree, s, e, index):
# Leaf Node
if (s == e):
tree[index] = arr[s]
return
# Finding mid
mid = (s + e) // 2
buildTree(arr, tree, s, mid, 2 * index + 1)
buildTree(arr, tree, mid + 1, e, 2 * index + 2)
# Updating current node
# by the maximum of its children
tree[index] = max(tree[2 * index + 1], tree[2 * index + 2])
# Function to find the maximum
# element in a given range
def query(tree, s, e, index, l, r):
if (l > e or r < s):
return -sys.maxsize -1
if (l <= s and r >= e):
return tree[index]
mid = (s + e) // 2
left = query(tree, s, mid,2 * index + 1, l, r)
right = query(tree, mid + 1, e, 2 * index + 2, l, r)
return max(left, right)
# Function to replace each array element by
# the maximum of K next and K previous elements
def updateArray(arr, K):
global MAXN
# To store the segment tree
tree = [0 for i in range(MAXN)]
N = len(arr)
buildTree(arr, tree, 0, N - 1, 0)
for i in range(N):
# For 0th index only find
# the maximum out of 1 to i+K
if (i == 0):
print(query(tree, 0, N - 1, 0, 1, min(i + K, N - 1)),end = ' ')
continue
# For (N-1)th index only find
# the maximum out of 0 to (N-2)
if (i == N - 1):
print(query(tree, 0, N - 1, 0, max(0, i - K), N - 2))
continue
# Maximum from (i-K) to (i-1)
left = query(tree, 0, N - 1, 0, max(i - K, 0), i - 1)
# Maximum from (i+1) to (i+K)
right = query(tree, 0, N - 1, 0, i + 1, min(i + K, N - 1))
print(max(left, right),end = ' ')
# Driver Code
arr = [12, 5, 3, 9, 21, 36, 17]
K = 2
updateArray(arr, K)
# This code is contributed by shinjanpatra
C#
// C# code for the above approach
using System;
class GFG {
static int MAXN = 500001;
// Function to build the tree
static void buildTree(int[] arr, int[] tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s, mid, 2 * index + 1);
buildTree(arr, tree, mid + 1, e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index] = Math.Max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
static int query(int[] tree, int s, int e, int index,
int l, int r)
{
if (l > e || r < s) {
return Int32.MinValue;
}
if (l <= s && r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid, 2 * index + 1, l, r);
int right
= query(tree, mid + 1, e, 2 * index + 2, l, r);
return Math.Max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
static void updateArray(int[] arr, int K)
{
// To store the segment tree
int[] tree = new int[MAXN];
int N = arr.Length;
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i) {
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
Console.Write(query(tree, 0, N - 1, 0, 1,
Math.Min(i + K, N - 1))
+ " ");
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
Console.Write(query(tree, 0, N - 1, 0,
Math.Max(0, i - K),
N - 2));
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1, 0,
Math.Max(i - K, 0), i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0, N - 1, 0, i + 1,
Math.Min(i + K, N - 1));
Console.Write(Math.Max(left, right) + " ");
}
}
// Driver Code
public static void Main()
{
int[] arr = { 12, 5, 3, 9, 21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
}
// This code is contributed by ukasp.
Javascript
输出
5 12 21 36 36 21 36
时间复杂度: O(N*N)
辅助空间: O(1)
有效方法:可以使用段树来解决这个问题。因此,构造一个范围最大分段树,其中:
- 叶节点是输入数组的元素。
- 每个内部节点代表其所有子节点的最大值。
现在,在构建线段树之后,找到从(iK)到(i-1)的最大值,比如左边和(i+1)到(i+K)的最大值,比如在这个线段树上使用查询。将arr[i]替换为left和right的最大值。
下面是上述方法的实现:
C++
// C++ code for the above approach
#define MAXN 500001
#include
using namespace std;
// Function to build the tree
void buildTree(vector& arr,
vector& tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s,
mid, 2 * index + 1);
buildTree(arr, tree, mid + 1,
e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index]
= max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
int query(vector& tree, int s,
int e, int index, int l,
int r)
{
if (l > e or r < s) {
return INT_MIN;
}
if (l <= s and r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid,
2 * index + 1, l, r);
int right
= query(tree, mid + 1, e,
2 * index + 2, l, r);
return max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
void updateArray(vector& arr, int K)
{
// To store the segment tree
vector tree(MAXN);
int N = arr.size();
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i) {
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
cout << query(tree, 0, N - 1, 0, 1,
min(i + K, N - 1))
<< ' ';
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
cout << query(tree, 0, N - 1,
0, max(0, i - K),
N - 2);
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1,
0, max(i - K, 0),
i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0,
N - 1, 0, i + 1,
min(i + K, N - 1));
cout << max(left, right) << ' ';
}
}
// Driver Code
int main()
{
vector arr = { 12, 5, 3, 9,
21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
Java
// Java code for the above approach
import java.io.*;
class GFG {
static int MAXN = 500001;
// Function to build the tree
static void buildTree(int[] arr, int[] tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s, mid, 2 * index + 1);
buildTree(arr, tree, mid + 1, e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index] = Math.max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
static int query(int[] tree, int s, int e, int index,
int l, int r)
{
if (l > e || r < s) {
return Integer.MIN_VALUE;
}
if (l <= s && r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid, 2 * index + 1, l, r);
int right
= query(tree, mid + 1, e, 2 * index + 2, l, r);
return Math.max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
static void updateArray(int[] arr, int K)
{
// To store the segment tree
int[] tree = new int[MAXN];
int N = arr.length;
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i)
{
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
System.out.print(query(tree, 0, N - 1, 0, 1,
Math.min(i + K, N - 1))
+ " ");
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
System.out.println(query(tree, 0, N - 1, 0,
Math.max(0, i - K),
N - 2));
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1, 0,
Math.max(i - K, 0), i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0, N - 1, 0, i + 1,
Math.min(i + K, N - 1));
System.out.print(Math.max(left, right) + " ");
}
}
// Driver Code
public static void main (String[] args)
{
int[] arr = { 12, 5, 3, 9, 21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
}
// This code is contributed by Shubham Singh.
Python3
# Python code for the above approach
import sys
MAXN = 500001
# Function to build the tree
def buildTree(arr, tree, s, e, index):
# Leaf Node
if (s == e):
tree[index] = arr[s]
return
# Finding mid
mid = (s + e) // 2
buildTree(arr, tree, s, mid, 2 * index + 1)
buildTree(arr, tree, mid + 1, e, 2 * index + 2)
# Updating current node
# by the maximum of its children
tree[index] = max(tree[2 * index + 1], tree[2 * index + 2])
# Function to find the maximum
# element in a given range
def query(tree, s, e, index, l, r):
if (l > e or r < s):
return -sys.maxsize -1
if (l <= s and r >= e):
return tree[index]
mid = (s + e) // 2
left = query(tree, s, mid,2 * index + 1, l, r)
right = query(tree, mid + 1, e, 2 * index + 2, l, r)
return max(left, right)
# Function to replace each array element by
# the maximum of K next and K previous elements
def updateArray(arr, K):
global MAXN
# To store the segment tree
tree = [0 for i in range(MAXN)]
N = len(arr)
buildTree(arr, tree, 0, N - 1, 0)
for i in range(N):
# For 0th index only find
# the maximum out of 1 to i+K
if (i == 0):
print(query(tree, 0, N - 1, 0, 1, min(i + K, N - 1)),end = ' ')
continue
# For (N-1)th index only find
# the maximum out of 0 to (N-2)
if (i == N - 1):
print(query(tree, 0, N - 1, 0, max(0, i - K), N - 2))
continue
# Maximum from (i-K) to (i-1)
left = query(tree, 0, N - 1, 0, max(i - K, 0), i - 1)
# Maximum from (i+1) to (i+K)
right = query(tree, 0, N - 1, 0, i + 1, min(i + K, N - 1))
print(max(left, right),end = ' ')
# Driver Code
arr = [12, 5, 3, 9, 21, 36, 17]
K = 2
updateArray(arr, K)
# This code is contributed by shinjanpatra
C#
// C# code for the above approach
using System;
class GFG {
static int MAXN = 500001;
// Function to build the tree
static void buildTree(int[] arr, int[] tree, int s,
int e, int index)
{
// Leaf Node
if (s == e) {
tree[index] = arr[s];
return;
}
// Finding mid
int mid = (s + e) / 2;
buildTree(arr, tree, s, mid, 2 * index + 1);
buildTree(arr, tree, mid + 1, e, 2 * index + 2);
// Updating current node
// by the maximum of its children
tree[index] = Math.Max(tree[2 * index + 1],
tree[2 * index + 2]);
}
// Function to find the maximum
// element in a given range
static int query(int[] tree, int s, int e, int index,
int l, int r)
{
if (l > e || r < s) {
return Int32.MinValue;
}
if (l <= s && r >= e) {
return tree[index];
}
int mid = (s + e) / 2;
int left = query(tree, s, mid, 2 * index + 1, l, r);
int right
= query(tree, mid + 1, e, 2 * index + 2, l, r);
return Math.Max(left, right);
}
// Function to replace each array element by
// the maximum of K next and K previous elements
static void updateArray(int[] arr, int K)
{
// To store the segment tree
int[] tree = new int[MAXN];
int N = arr.Length;
buildTree(arr, tree, 0, N - 1, 0);
for (int i = 0; i < N; ++i) {
// For 0th index only find
// the maximum out of 1 to i+K
if (i == 0) {
Console.Write(query(tree, 0, N - 1, 0, 1,
Math.Min(i + K, N - 1))
+ " ");
continue;
}
// For (N-1)th index only find
// the maximum out of 0 to (N-2)
if (i == N - 1) {
Console.Write(query(tree, 0, N - 1, 0,
Math.Max(0, i - K),
N - 2));
continue;
}
// Maximum from (i-K) to (i-1)
int left = query(tree, 0, N - 1, 0,
Math.Max(i - K, 0), i - 1);
// Maximum from (i+1) to (i+K)
int right = query(tree, 0, N - 1, 0, i + 1,
Math.Min(i + K, N - 1));
Console.Write(Math.Max(left, right) + " ");
}
}
// Driver Code
public static void Main()
{
int[] arr = { 12, 5, 3, 9, 21, 36, 17 };
int K = 2;
updateArray(arr, K);
}
}
// This code is contributed by ukasp.
Javascript
输出
5 12 21 36 36 21 36
时间复杂度: O(NlogN)
辅助空间: O(1)