Moving Stones Until Consecutive II in C++


Suppose we are considering an infinite number line, here the position of the i−th stone is given by array stones and stones[i] is indicating ith stone position. A stone is an endpoint stone if it has the smallest or largest position. Now in each turn, we pick up an endpoint stone and move it to an unoccupied position so that it is no longer an endpoint stone.

If the stones are at say, stones = [1,2,5], we cannot move the endpoint stone at position 5, because moving it to any position (such as 0, or 3) will still keep that stone as an endpoint stone.

This game will stop when we cannot make any more moves. So the stones are in consecutive positions.

Here we have to find when the game ends, so what will be the minimum and maximum number of moves that we could have made? Find the answer as a pair [min_moves, max_moves]

For example, if the input is like [7,3,9], then the result will be [1,3]

To solve this, we will follow these steps −

  • Define an array ans of size 2

  • ans[0] := inf, ans[1] := −inf and n := size of a

  • sort the array a

  • x := 1

  • while x < n and a[x] & a[x − 1] is same as 1, do −

    • increase x by 1

  • if x is same as n, then,

    • return a pair {0,0}

  • minVal := 0, j := 1

  • for initializing i := 0, when i < a.size(, increase i by 1 do −

    • curr := a[i], lastPossible = a[i]

    • if lastPossible > a[n - 1], then, Come out from the loopp

    • spaceInBetween := false

    • if j <= i, then,

      • j := i + 1

    • while j < n and a[j] <= lastPossible, do:

      • if a[j] - a[j - 1]) > 1, then,

        • spaceInBetween := true

      • if a[j] - a[j - 1]) > 1, then,

      • increase j by 1

    • idx := j - 1

    • if n - (idx - i + 1) > 1, then,

      • spaceInBetween := true

  • ballLeft := i, ballRight := n - (idx + 1)

  • minVal := ballLeft + ballRight + (0 when spaceInBetween is true, otherwise 1)

  • ans[0] := minimum of minVal ans ans[0]

  • ans[1] := max of a[n - 2] - a[0] and a[n - 1] - a[1]) - (n - 2),

  • return ans

  • from the main method call solve(stones)

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
class Solution {
   public:
   vector<int> solve(vector<int> a) {
      vector <int> ans(2);
      ans[0] = INT_MAX;
      ans[1] = INT_MIN;
      int n = a.size();
      sort(a.begin(), a.end());
      int x = 1;
      while(x < n && a[x] - a[x - 1] == 1)
         x ++;
      if(x == n){
         return {0,0};
      }
      int minVal = 0;
      int j = 1;
      for(int i = 0; i < a.size(); i++){
         int curr = a[i];
         int lastPossible = a[i] + n - 1;
         if(lastPossible > a[n - 1])
            break;
         bool spaceInBetween = false;
         if(j <= i)
            j = i + 1;
            while(j < n && a[j] <= lastPossible){
               if((a[j] - a[j - 1]) > 1) {
                  spaceInBetween = true;
               }
               j++;
            }
           int idx = j - 1;
           if(n - (idx - i + 1) > 1)
              spaceInBetween = true;
           int ballLeft = i;
           int ballRight = n - (idx + 1);
           minVal = ballLeft + ballRight + (spaceInBetween? 0 : 1);
           ans[0] = min(minVal, ans[0]);
        }
       ans[1] = max(a[n - 2] - a[0], a[n - 1] - a[1]) - (n -2);
       return ans;
   }
   vector<int> numMovesStonesII(vector<int>& stones) {
      return solve(stones);
   }
};
main(){
   Solution ob;
   vector<int> v1 = {7,3,9};
   print_vector(ob.numMovesStonesII(v1));
}

Input

[7,3,9]

Output

[1, 3, ]

Updated on: 13-Nov-2020

135 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements