📌  相关文章
📜  用最多 K 个下一个和 K 个前一个元素替换每个数组元素

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

用最多 K 个下一个和 K 个前一个元素替换每个数组元素

给定一个数组arr ,任务是将每个数组元素替换为 K 下一个和 K 前一个元素中的最大值。

例子:

天真的方法:按照以下步骤解决此问题:

  1. 遍历数组从i=0i并且对于每个元素:
    • j=iKj<=i+K运行另一个循环,并将arr[i]更改为 K next 和 K previous 元素的最大值。
  2. 在上述循环结束后打印数组。

下面是上述方法的实现:

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]替换为leftright的最大值。

下面是上述方法的实现:

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)