📌  相关文章
📜  对于给定数组中的每个元素,最大化两个最接近的其他数组的乘积

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

对于给定数组中的每个元素,最大化两个最接近的其他数组的乘积

给定大小为M的数组arr1[]和大小为N且长度至少为 2 的数组arr2[] ,任务是针对arr1[] 中的每个元素,最大化arr2[]中最接近arr1中元素的两个元素的乘积[]。最接近的元素必须出现在不同的索引上。

例子:

方法:给定的问题可以使用贪心方法来解决。这个想法是按升序对数组arr2进行排序,然后对于arr1中的每个元素,使用二进制搜索在 arr2中找到最接近它的元素。可以按照以下步骤解决问题:

  • 对数组arr2进行升序排序
  • 迭代数组arr1并在每次迭代时对arr2应用二进制搜索以找到最接近arr1[i] 的元素的索引,例如x
    • 如果不存在先前的索引x-1,则返回arr2[x] * arr2[x+1]
    • Else 如果不存在下一个索引x+1,则返回arr2[x] * arr2[x-1]
    • 否则,检查arr2[x-1]arr2[x+1]之间的哪个元素更接近arr1[i]:
      • 如果arr2[x-1]更接近,则返回arr2[x] * arr2[x-1]
      • 否则,如果arr2[x+1]更接近,则返回arr2[x] * arr2[x+1]
      • 否则,如果arr2[x-1]arr2[x+1]都与arr1[i]等距,则返回arr2[x] * arr2[x+1]arr2[x] * arr2[x+ 1]

下面是上述方法的实现。

C++
// C++ code for the above approach
#include 
using namespace std;
 
// Binary search function to
// find element closest to arr1[i]
int binarySearch(int num,
                 vector arr)
{
 
    // Initialize left right and mid
    int mid = -1, left = 0,
        right = arr.size() - 1;
 
    // Initialize closest index and
    // smallest difference
    int closestInd = -1;
    int smallestDiff = INT_MAX;
 
    while (left <= right)
    {
 
        mid = (left + right) >> 1;
 
        if (abs(arr[mid] - num) < smallestDiff)
        {
 
            // Update smallest difference
            smallestDiff = abs(arr[mid] - num);
 
            // Update closest index
 
            closestInd = mid;
        }
        else if (abs(arr[mid] - num) == smallestDiff)
        {
            if (arr[mid] > arr[closestInd])
                closestInd = mid;
        }
 
        if (arr[mid] == num)
        {
 
            // This is the closest
            // element index
            return mid;
        }
        else if (arr[mid] < num)
        {
 
            // Closer element lies
            // to the right
            left = mid + 1;
        }
        else
        {
 
            // Closer element lies
            // to the left
            right = mid - 1;
        }
    }
 
    return closestInd;
}
 
// Function to find the maximum product of
// Closest two elements in second array
// for every element in the first array
vector maxProdClosest(vector arr1,
                           vector arr2)
{
 
    // Find the length of both arrays
    int M = arr1.size(), N = arr2.size();
 
    // Initialize an array to store
    // the result for every element
    vector ans(M);
 
    // Sort the second array arr2
    sort(arr2.begin(), arr2.end());
 
    // Iterate the array arr1
    for (int i = 0; i < M; i++)
    {
 
        // Apply binary search and
        // find the index of closest
        // element to arr1[i] in arr2
        int ind = binarySearch(arr1[i],
                               arr2);
 
        // No element at previous index
        if (ind == 0)
        {
 
            ans[i] = arr2[ind] * arr2[ind + 1];
        }
 
        // No element at the next index
        else if (ind == N - 1)
        {
 
            ans[i] = arr2[ind] * arr2[ind - 1];
        }
 
        // Elements at the next and
        // previous indices are present
        else
        {
 
            // arr2[ind - 1] is closer
            // to arr1[i]
            if (abs(arr2[ind - 1] - arr1[i]) < abs(arr2[ind + 1] - arr1[i]))
            {
 
                ans[i] = arr2[ind] * arr2[ind - 1];
            }
            else if (
 
                // arr2[ind + 1] is
                // closer to arr1[i]
                abs(arr2[ind - 1] - arr1[i]) > abs(arr2[ind + 1] - arr1[i]))
            {
 
                ans[i] = arr2[ind] * arr2[ind + 1];
            }
 
            // If both arr2[ind - 1] and
            // arr2[ind + 1] are
            // equidistant from arr1[i]
            else
            {
 
                ans[i] = max(
                    arr2[ind] * arr2[ind - 1],
                    arr2[ind] * arr2[ind + 1]);
            }
        }
    }
 
    // Return the resulting array
    return ans;
}
 
// Driver function
int main()
{
 
    // Initialize the arrays
    vector arr1 = {5, 10, 17, 22, -1};
    vector arr2 = {-1, 26, 5, 20,
                        14, 17, -7};
 
    // Call the function
    vector res = maxProdClosest(arr1,
                                     arr2);
 
    // Iterate the array and
    // print the result
    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i] << " ";
    }
}
 
// This code is contributed by Potta Lokesh


Java
// Java implementation for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find the maximum product of
    // Closest two elements in second array
    // for every element in the first array
    public static int[] maxProdClosest(int[] arr1,
                                       int[] arr2)
    {
 
        // Find the length of both arrays
        int M = arr1.length, N = arr2.length;
 
        // Initialize an array to store
        // the result for every element
        int[] ans = new int[M];
 
        // Sort the second array arr2
        Arrays.sort(arr2);
 
        // Iterate the array arr1
        for (int i = 0; i < M; i++) {
 
            // Apply binary search and
            // find the index of closest
            // element to arr1[i] in arr2
            int ind = binarySearch(arr1[i],
                                   arr2);
 
            // No element at previous index
            if (ind == 0) {
 
                ans[i] = arr2[ind] * arr2[ind + 1];
            }
 
            // No element at the next index
            else if (ind == N - 1) {
 
                ans[i] = arr2[ind] * arr2[ind - 1];
            }
 
            // Elements at the next and
            // previous indices are present
            else {
 
                // arr2[ind - 1] is closer
                // to arr1[i]
                if (Math.abs(arr2[ind - 1]
                             - arr1[i])
                    < Math.abs(arr2[ind + 1]
                               - arr1[i])) {
 
                    ans[i] = arr2[ind] * arr2[ind - 1];
                }
                else if (
 
                    // arr2[ind + 1] is
                    // closer to arr1[i]
                    Math.abs(arr2[ind - 1]
                             - arr1[i])
                    > Math.abs(arr2[ind + 1]
                               - arr1[i])) {
 
                    ans[i] = arr2[ind] * arr2[ind + 1];
                }
 
                // If both arr2[ind - 1] and
                // arr2[ind + 1] are
                // equidistant from arr1[i]
                else {
 
                    ans[i] = Math.max(
                        arr2[ind] * arr2[ind - 1],
                        arr2[ind] * arr2[ind + 1]);
                }
            }
        }
 
        // Return the resulting array
        return ans;
    }
 
    // Binary search function to
    // find element closest to arr1[i]
    public static int binarySearch(int num,
                                   int[] arr)
    {
 
        // Initialize left right and mid
        int mid = -1, left = 0,
            right = arr.length - 1;
 
        // Initialize closest index and
        // smallest difference
        int closestInd = -1;
        int smallestDiff = Integer.MAX_VALUE;
 
        while (left <= right) {
 
            mid = (left + right) >> 1;
 
            if (Math.abs(arr[mid] - num)
                < smallestDiff) {
 
                // Update smallest difference
                smallestDiff = Math.abs(arr[mid] - num);
 
                // Update closest index
 
                closestInd = mid;
            }
            else if (Math.abs(arr[mid] - num)
                     == smallestDiff) {
                if (arr[mid] > arr[closestInd])
                    closestInd = mid;
            }
 
            if (arr[mid] == num) {
 
                // This is the closest
                // element index
                return mid;
            }
            else if (arr[mid] < num) {
 
                // Closer element lies
                // to the right
                left = mid + 1;
            }
            else {
 
                // Closer element lies
                // to the left
                right = mid - 1;
            }
        }
 
        return closestInd;
    }
 
    // Driver function
    public static void main(String[] args)
    {
 
        // Initialize the arrays
        int[] arr1 = { 5, 10, 17, 22, -1 };
        int[] arr2 = { -1, 26, 5, 20,
                       14, 17, -7 };
 
        // Call the function
        int[] res = maxProdClosest(arr1,
                                   arr2);
 
        // Iterate the array and
        // print the result
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i] + " ");
        }
    }
}


Python3
# python3 code for the above approach
INT_MAX = 2147483647
 
# Binary search function to
# find element closest to arr1[i]
def binarySearch(num, arr):
 
    # Initialize left right and mid
    mid, left, right = -1, 0, len(arr) - 1
 
    # Initialize closest index and
    # smallest difference
    closestInd = -1
    smallestDiff = INT_MAX
 
    while (left <= right):
 
        mid = (left + right) >> 1
 
        if (abs(arr[mid] - num) < smallestDiff):
 
            # Update smallest difference
            smallestDiff = abs(arr[mid] - num)
 
            # Update closest index
 
            closestInd = mid
 
        elif (abs(arr[mid] - num) == smallestDiff):
 
            if (arr[mid] > arr[closestInd]):
                closestInd = mid
 
        if (arr[mid] == num):
 
            # This is the closest
            # element index
            return mid
 
        elif (arr[mid] < num):
 
            # Closer element lies
            # to the right
            left = mid + 1
 
        else:
 
            # Closer element lies
            # to the left
            right = mid - 1
 
    return closestInd
 
# Function to find the maximum product of
# Closest two elements in second array
# for every element in the first array
def maxProdClosest(arr1, arr2):
 
    # Find the length of both arrays
    M, N = len(arr1), len(arr2)
 
    # Initialize an array to store
    # the result for every element
    ans = [0 for _ in range(M)]
 
    # Sort the second array arr2
    arr2.sort()
 
    # Iterate the array arr1
    for i in range(0, M):
 
        # Apply binary search and
        # find the index of closest
        # element to arr1[i] in arr2
        ind = binarySearch(arr1[i], arr2)
 
        # No element at previous index
        if (ind == 0):
 
            ans[i] = arr2[ind] * arr2[ind + 1]
 
        # No element at the next index
        elif (ind == N - 1):
 
            ans[i] = arr2[ind] * arr2[ind - 1]
 
        # Elements at the next and
        # previous indices are present
        else:
 
            # arr2[ind - 1] is closer
            # to arr1[i]
            if (abs(arr2[ind - 1] - arr1[i]) < abs(arr2[ind + 1] - arr1[i])):
 
                ans[i] = arr2[ind] * arr2[ind - 1]
 
            elif (
 
                    # arr2[ind + 1] is
                    # closer to arr1[i]
                    abs(arr2[ind - 1] - arr1[i]) > abs(arr2[ind + 1] - arr1[i])):
 
                ans[i] = arr2[ind] * arr2[ind + 1]
 
            # If both arr2[ind - 1] and
            # arr2[ind + 1] are
            # equidistant from arr1[i]
            else:
 
                ans[i] = max(
                    arr2[ind] * arr2[ind - 1],
                    arr2[ind] * arr2[ind + 1])
 
    # Return the resulting array
    return ans
 
# Driver function
if __name__ == "__main__":
 
    # Initialize the arrays
    arr1 = [5, 10, 17, 22, -1]
    arr2 = [-1, 26, 5, 20, 14, 17, -7]
 
    # Call the function
    res = maxProdClosest(arr1, arr2)
 
    # Iterate the array and
    # print the result
    for i in range(0, len(res)):
 
        print(res[i], end=" ")
 
    # This code is contributed by rakeshsahni


C#
// C# implementation for the above approach
using System;
class GFG {
 
    // Function to find the maximum product of
    // Closest two elements in second array
    // for every element in the first array
    public static int[] maxProdClosest(int[] arr1,
                                       int[] arr2)
    {
 
        // Find the length of both arrays
        int M = arr1.Length, N = arr2.Length;
 
        // Initialize an array to store
        // the result for every element
        int[] ans = new int[M];
 
        // Sort the second array arr2
        Array.Sort(arr2);
 
        // Iterate the array arr1
        for (int i = 0; i < M; i++) {
 
            // Apply binary search and
            // find the index of closest
            // element to arr1[i] in arr2
            int ind = binarySearch(arr1[i], arr2);
 
            // No element at previous index
            if (ind == 0) {
 
                ans[i] = arr2[ind] * arr2[ind + 1];
            }
 
            // No element at the next index
            else if (ind == N - 1) {
 
                ans[i] = arr2[ind] * arr2[ind - 1];
            }
 
            // Elements at the next and
            // previous indices are present
            else {
 
                // arr2[ind - 1] is closer
                // to arr1[i]
                if (Math.Abs(arr2[ind - 1] - arr1[i])
                    < Math.Abs(arr2[ind + 1] - arr1[i])) {
 
                    ans[i] = arr2[ind] * arr2[ind - 1];
                }
                else if (
 
                    // arr2[ind + 1] is
                    // closer to arr1[i]
                    Math.Abs(arr2[ind - 1] - arr1[i])
                    > Math.Abs(arr2[ind + 1] - arr1[i])) {
 
                    ans[i] = arr2[ind] * arr2[ind + 1];
                }
 
                // If both arr2[ind - 1] and
                // arr2[ind + 1] are
                // equidistant from arr1[i]
                else {
 
                    ans[i] = Math.Max(
                        arr2[ind] * arr2[ind - 1],
                        arr2[ind] * arr2[ind + 1]);
                }
            }
        }
 
        // Return the resulting array
        return ans;
    }
 
    // Binary search function to
    // find element closest to arr1[i]
    public static int binarySearch(int num, int[] arr)
    {
 
        // Initialize left right and mid
        int mid = -1, left = 0, right = arr.Length - 1;
 
        // Initialize closest index and
        // smallest difference
        int closestInd = -1;
        int smallestDiff = Int32.MaxValue;
 
        while (left <= right) {
 
            mid = (left + right) >> 1;
 
            if (Math.Abs(arr[mid] - num) < smallestDiff) {
 
                // Update smallest difference
                smallestDiff = Math.Abs(arr[mid] - num);
 
                // Update closest index
 
                closestInd = mid;
            }
            else if (Math.Abs(arr[mid] - num)
                     == smallestDiff) {
                if (arr[mid] > arr[closestInd])
                    closestInd = mid;
            }
 
            if (arr[mid] == num) {
 
                // This is the closest
                // element index
                return mid;
            }
            else if (arr[mid] < num) {
 
                // Closer element lies
                // to the right
                left = mid + 1;
            }
            else {
 
                // Closer element lies
                // to the left
                right = mid - 1;
            }
        }
 
        return closestInd;
    }
 
    // Driver function
    public static void Main(string[] args)
    {
 
        // Initialize the arrays
        int[] arr1 = { 5, 10, 17, 22, -1 };
        int[] arr2 = { -1, 26, 5, 20, 14, 17, -7 };
 
        // Call the function
        int[] res = maxProdClosest(arr1, arr2);
 
        // Iterate the array and
        // print the result
        for (int i = 0; i < res.Length; i++) {
            Console.Write(res[i] + " ");
        }
    }
}
 
// This code is contributed by ukasp.


Javascript



输出
-5 70 340 520 7 

时间复杂度: O(N * log N + M * log N)
辅助空间: O(1)