Minimize Travel Distance to Collect K Objects on X-Axis

By | October 1, 2023

N objects are placed on X-axis, and coordinates are given. Starting your journey with coordinate 0, find minimum distance you need to travel to collect K objects (If multiple objects are placed on same position, you may collect some or all of them).

Examples:

Input: arr[] = {10, -10, -30, 20, 50},  K = 3
Output: 40
Explanation: 
Start with 0 (initial position) journey will be 0 --> (-10) --> 10 --> 20 .
Sum of distance is |-10-0| + |10-(-10)| + |20-10| = 40, which is minimum possible.

Input: arr[] = {4, -3, 5},  K = 2
Output: 5
Explanation: 
Start with 0 (initial position) journey will be 0 --> 4 --> 5 .
Sum of distance is |4-0|+ |5-4| = 5, which is minimum possible.

Recommended: Why Learn C++?

Approach:
Here are some observations and steps to solve given problem

Observations:-

  • If two objects with coordinates at x1 and x2 are collected, both from positive side (or both from negative side) then total distance will be max(|x1|, |x2|), if current position is 0.
  • Switching direction (from negative to positive Or vice versa) more than 1 time, will add some additional distance to answer.

Solution:-

  • Sort all the points in increasing order of coordinates.
  • Select all subarrays of length K, and for each subarray optimal total distance will be as :-
    • If all the coordinates are negative, leftmost coordinate denotes total distance.
    • If all the coordinates are positive, rightmost coordinate denotes total distance.
    • If subarray contains both negative and positive, then there are 2 ways – select all negative first and then switch to positive Or vice versa.
  • Minimum distance among all these subarrays, is our optimal answer.

Below is the implementation of above approach:

#include <bits/stdc++.h>

using namespace std;

int minDistance(int arr[], int N, int K) {
  if (N < K)
    return -1;

  // sort the coordinates
  sort(arr, arr + N);
  int ans = 1e9;

  // select subarray of length K, starting at index i
  for (int i = 0; i < N - K + 1; i++) {
    int left = arr[i];
    int right = arr[i + K - 1];

    if (right <= 0) {
      // both ends are negative side
      left = abs(left);
      ans = min(ans, left);
    } else if (left >= 0) {
      // both ends are positive side
      ans = min(ans, right);
    } else {
      left = abs(left);

      // first left and then right
      ans = min(ans, left + left + right);

      // first right and then left
      ans = min(ans, right + right + left);
    }
  }

  return ans;
}

// Driver code
int main() {
  int N = 5;
  int arr[] = { 10, -10, -30, 20, 50 };
  int K = 3;

  cout << minDistance(arr, N, K);

  return 0;
}

Output:

40

Time Complexity: O(N logN)
Space Complexity: O(N)

Please write comments if you find anything incorrect. A gentle request to share this topic on your social media profile.

Author: Mithlesh Upadhyay

I hold an M.Tech degree in Artificial Intelligence (2023) from Delhi Technological University (DTU) and possess over 4 years of experience. I worked at GeeksforGeeks, leading teams and managing content, including GATE CS, Test Series, Placements, C, and C++. I've also contributed technical content to companies like MarsDev, Tutorialspoint, StudyTonight, TutorialCup, and Guru99. My skill set includes coding, Data Structures and Algorithms (DSA), and Object-Oriented Programming (OOPs). I'm proficient in C++, Python, JavaScript, HTML, CSS, Bootstrap, React.js, Node.js, MongoDB, Django, and Data Science.