📌  相关文章
📜  找到一个点,它到一条线上所有给定点的距离之和为 K

📅  最后修改于: 2021-09-06 06:08:47             🧑  作者: Mango

给定一个由N 个整数组成的排序数组arr[] ,代表一条线上的点和一个整数K ,任务是找到第一个点和最后一个点之间的任何点P ,使得所有给定点到P的距离之和相等到K。如果不存在这样的点,则打印“-1”

例子:

方法:给定的问题可以基于这样的观察来解决:距离的总和在阵列的中位数处将是最小的,并且当从中位数向任何末端移动时距离会增加。因此,我们的想法是对数组的两半执行二分搜索并检查是否有任何点的距离等于K 。请按照以下步骤解决问题:

  • 声明一个函数,计算所有点到给定点的距离总和。
  • 对数组的右半部分执行二分搜索,如下所示:
    • 如果N 的值为奇数,则将left的值更新为arr[N / 2] 。否则,将left的值更新为arr[N / 2 – 1] + 1
    • 如果N 的值为偶数,则将right的值更新为arr[N – 1]
    • 找到距离的总和,比如temp from mid = (left + right) / 2并检查temp的值是否等于K 。如果发现为true ,则打印mid的值作为结果。
    • 如果K < temp的值,则将right的值更新为mid – 1 。否则,将left的值更新为mid + 1
  • 在数组的左半部分执行二分搜索:
    • 设置left = arr[0]right = arr[N / 2] – 1 的值
    • 查找距离的总和说,从2月中旬温度=(左+右)/并检查是否温度等于K或不是。如果发现为true ,则打印mid的值作为结果。
    • 如果K > temp的值,则更新right = mid – 1的值。否则,更新left = mid + 1的值。
  • 如果在左半部分和右半部分没有找到值,则打印“-1”作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the sum of distances
// of all points from a given point
int findSum(int* arr, int N, int pt)
{
    // Stores sum of distances
    int sum = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
        sum += abs(arr[i] - pt);
    }
 
    // Return the sum
    return sum;
}
 
// Function to find such a point having
// sum of distances of all other points
// from this point equal to K
void findPoint(int* arr, int N, int K)
{
    // If N is odd keep left as arr[n / 2]
    // else keep left as arr[n / 2 - 1] + 1;
    int left;
 
    if (N % 2) {
        left = arr[N / 2];
    }
    else {
        left = arr[N / 2 - 1] + 1;
    }
 
    // Keep right as arr[N - 1]
    int right = arr[N - 1];
 
    // Perform binary search in the
    // right half
    while (left <= right) {
 
        // Calculate the mid index
        // of the range
        int mid = (left + right) / 2;
 
        int temp = findSum(arr, N, mid);
 
        // If temp is equal to K
        if (temp == K) {
 
            // Print the value of mid
            cout << mid << endl;
            return;
        }
 
        // If the value of K < temp
        else if (K < temp) {
 
            // Update right to mid - 1
            right = mid - 1;
        }
 
        // If the value of K > temp
        else {
 
            // Update left to mid + 1
            left = mid + 1;
        }
    }
 
    // Update the value of left
    left = arr[0];
 
    // Update the value of right
    right = arr[N / 2] - 1;
 
    // Perform binary search on the
    // left half
    while (left <= right) {
 
        // Calculate the mid index
        // of the range
        int mid = (left + right) / 2;
 
        int temp = findSum(arr, N, mid);
 
        // If temp is equal to K
        if (temp == K) {
 
            // Print mid
            cout << mid << endl;
            return;
        }
 
        // if K > temp
        else if (K > temp) {
 
            // Update right to mid - 1
            right = mid - 1;
        }
 
        // If K < temp
        else {
 
            // Update left to mid + 1
            left = mid + 1;
        }
    }
 
    // If no such point found
    cout << "-1" << endl;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 3, 6, 7, 11 };
    int K = 18;
    int N = sizeof(arr) / sizeof(arr[0]);
    findPoint(arr, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.lang.*;
 
class GFG{
 
// Function to find the sum of distances
// of all points from a given point
public static int findSum(int arr[], int N,
                          int pt)
{
     
    // Stores sum of distances
    int sum = 0;
 
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
        sum += Math.abs(arr[i] - pt);
    }
 
    // Return the sum
    return sum;
}
 
// Function to find such a point having
// sum of distances of all other points
// from this point equal to K
public static void findPoint(int arr[], int N, int K)
{
     
    // If N is odd keep left as arr[n / 2]
    // else keep left as arr[n / 2 - 1] + 1;
    int left;
 
    if (N % 2 != 0)
    {
        left = arr[N / 2];
    }
    else
    {
        left = arr[N / 2 - 1] + 1;
    }
 
    // Keep right as arr[N - 1]
    int right = arr[N - 1];
 
    // Perform binary search in the
    // right half
    while (left <= right)
    {
         
        // Calculate the mid index
        // of the range
        int mid = (left + right) / 2;
 
        int temp = findSum(arr, N, mid);
 
        // If temp is equal to K
        if (temp == K)
        {
             
            // Print the value of mid
            System.out.println(mid);
            return;
        }
 
        // If the value of K < temp
        else if (K < temp)
        {
             
            // Update right to mid - 1
            right = mid - 1;
        }
 
        // If the value of K > temp
        else
        {
             
            // Update left to mid + 1
            left = mid + 1;
        }
    }
 
    // Update the value of left
    left = arr[0];
 
    // Update the value of right
    right = arr[N / 2] - 1;
 
    // Perform binary search on the
    // left half
    while (left <= right)
    {
         
        // Calculate the mid index
        // of the range
        int mid = (left + right) / 2;
 
        int temp = findSum(arr, N, mid);
 
        // If temp is equal to K
        if (temp == K)
        {
             
            // Print mid
            System.out.println(mid);
            return;
        }
 
        // if K > temp
        else if (K > temp)
        {
             
            // Update right to mid - 1
            right = mid - 1;
        }
 
        // If K < temp
        else
        {
 
            // Update left to mid + 1
            left = mid + 1;
        }
    }
 
    // If no such point found
    System.out.println( "-1" );
}
 
// Driver Code
public static void main(String args[])
{
    int arr[] = { 1, 3, 6, 7, 11 };
    int K = 18;
    int N = arr.length;
     
    findPoint(arr, N, K);
}
}
 
// This code is contributed by SoumikMondal


Python3
# python 3 program for the above approach
 
# Function to find the sum of distances
# of all points from a given point
def findSum(arr, N, pt):
   
    # Stores sum of distances
    sum = 0
 
    # Traverse the array
    for i in range(N):
        sum += abs(arr[i] - pt)
 
    # Return the sum
    return sum
 
# Function to find such a point having
# sum of distances of all other points
# from this point equal to K
def findPoint(arr, N, K):
    # If N is odd keep left as arr[n / 2]
    # else keep left as arr[n / 2 - 1] + 1;
    left = 0
 
    if (N % 2):
        left = arr[N // 2]
    else:
        left = arr[N // 2 - 1] + 1
 
    # Keep right as arr[N - 1]
    right = arr[N - 1]
 
    # Perform binary search in the
    # right half
    while (left <= right):
 
        # Calculate the mid index
        # of the range
        mid = (left + right) // 2
 
        temp = findSum(arr, N, mid)
 
        # If temp is equal to K
        if (temp == K):
            # Print the value of mid
            print(mid)
            return
 
        # If the value of K < temp
        elif (K < temp):
            # Update right to mid - 1
            right = mid - 1
 
        # If the value of K > temp
        else:
            # Update left to mid + 1
            left = mid + 1
 
    # Update the value of left
    left = arr[0]
 
    # Update the value of right
    right = arr[N // 2] - 1
 
    # Perform binary search on the
    # left half
    while (left <= right):
        # Calculate the mid index
        # of the range
        mid = (left + right) // 2
 
        temp = findSum(arr, N, mid)
 
        # If temp is equal to K
        if (temp == K):
 
            # Print mid
            print(mid)
            return
 
        # if K > temp
        elif(K > temp):
            # Update right to mid - 1
            right = mid - 1
 
        # If K < temp
        else:
            # Update left to mid + 1
            left = mid + 1
 
    # If no such point found
    print("-1")
 
# Driver Code
if __name__ == '__main__':
    arr = [1, 3, 6, 7, 11]
    K = 18
    N = len(arr)
    findPoint(arr, N, K)
 
    # This code is contributed by SURENDRA_GANGWAR.


输出:
8

时间复杂度: O(N * log 2 (M – m)) 其中M是最大值, m数组的最小值。
辅助空间: O(1)