Find the last player to be able to remove a string from an array which is not already removed from other arrays


In this problem, two players play a game by removing the string from their array, which is not already removed from the opponent's array. We need to decide the winner of the game.

We can solve the problem using two different approaches. In the first approach, we can store the common strings with the set data structure. In the second approach, we can use a set to store already removed strings from both arrays.

Problem statement – We have given two arrays called arr and brr. The size of the array is N and M, respectively. We need to decide which player will win the game if they follow the below rules to play a game.

  • Player 1 takes the first turn.

  • If the current turn is of player 1, he removes the one string from the arr[] array if it is not already removed from the array brr[].

  • If the current turn is of player 2, he removes the one string from the brr[] array if it is not already removed from the array arr[].

  • If any player has no string to remove, he loses the game.

Sample examples

Input– arr = {"tuts"}, brr = {"tuts", "tutorialspoint"}

Output– ‘Player 2 won.’

Explanation– Player 1 removes the ‘tuts’, and Player 2 removes the ‘tutorialspoint’.

Now, player 1 has no string to remove, so he loses the game.

Input– arr = {"tuts", "point"}, brr = {"tuts", "tutorialspoint", "acd"}

Output– ‘Player 2 won.’

Explanation– Player 1 removes the ‘tuts’, and Player 2 removes the ‘tutorialspoint’.

Next, player 1 removes ‘point’, and player 2 removes ‘acd’. Now, player 1 has no string to remove, so he loses the game.

Input– arr = {"a ", "b"}, brr = {"a ", "c"}

Output– ‘Player 1 won.’

Explanation– Player 1 will remove ‘a’, and Player 2 will remove ‘c’.

After that, player 1 will remove ‘b’, and player 2 has no string to remove.

Approach 1

In this approach, we will find the common strings from both arrays. We assume that the player plays with common strings first, and after that player plays with uncommon strings. So, whoever player has more common strings, he can win the game.

Algorithm

  • Define the common Strings set.

  • Compare all arr[] and brr[] strings and add all common strings to the set.

  • We need to find the uncommon strings from the arr[] array.

    • Define the uncommonA set to store uncommon strings.

    • Traverse the arr[] array. Inside the loop, define the ‘flag’ variable and initialize it with the ‘false’ value.

    • If string at ith index is present in the ‘common Strings’ set, set a flag to true, and break the loop.

    • If ‘flag’ is false, insert the current string in the uncommonA.

  • Define the unCommonB set, and store all uncommon strings of brr[] in the set as we have done in the above steps for arr[].

  • If there are a total odd number of common strings, player 1 can take the last turn with common strings. So, to complete the turn, player 2 need to use one uncommon string. So, decrease the length of uncommonB by 1.

  • If the length of uncommonA is greater than lenBrr, return ‘player 1’. Else return ‘player 2’.

Example

#include <bits/stdc++.h>
using namespace std;
// function to find the winner
string findWinningPlayer(vector<string> arr, vector<string> brr){
   // set to store common strings
   set<string> commonStrings;
   // Finding common strings
   for (int i = 0; i < arr.size(); i++){
      for (int j = 0; j < brr.size(); j++){
          if (arr[i] == brr[j]){
              // insert common string to set
              commonStrings.insert(arr[i]);
              break;
          }
      }
   }
   // getting uncommon strings from A
   set<string> uncommonA;
   for (int i = 0; i < arr.size(); i++){
      bool flag = false;
      for (auto value : commonStrings){
          if (value == arr[i]){
              // If value == arr[i], it means string is common
              flag = true;
              break;
          }
      }
      if (!flag)
          uncommonA.insert(arr[i]);
   }
   // getting uncommon strings from B
   set<string> uncommonB;
   for (int i = 0; i < brr.size(); i++){
      bool flag = false;
      for (auto value : commonStrings){
          if (value == brr[i]){
              // If value == brr[i], it means string is common
              flag = true;
              break;
          }
      }
      if (!flag)
          uncommonB.insert(brr[i]);
   }
   int LenBrr = uncommonB.size();
   // If the size of commonStrings is odd, then decrease 1 common string from a set of uncommon strings of B
   if ((commonStrings.size()) % 2 == 1){
      // Update LenBrr
      LenBrr -= 1;
   }
   if (uncommonA.size() > LenBrr){
      return "Player 1 won!";
   }
   else{
      return "Player 2 won!";
   }
}
int main(){
   // Set of strings for player A
   vector<string> arr{"tuts"};
   // Set of strings for player B
   vector<string> brr{"tuts", "tutorialspoint"};
   cout << findWinningPlayer(arr, brr);
}

Output

Player 2 won!

Time complexity – O(N^2) as we find common strings.

Space complexity – O(N + M) as we store common and uncommon strings into the set..

Approach 2

In this approach, we will store the already used string to take turns in the set. After that, while taking the turn, if the player has no strings that are not present in the set, the player loses the game.

Algorithm

  • Insert all strings of arr[] to set1 and brr[] to set2.

  • Initialize the ‘turn’ variable with 1, as player 1 takes the first turn.

  • Use the while() loop to make infinite iterations.

  • In the loop, if turn == 1, and if set1 is empty, return ‘player 2’. If the set has value, remove the first value from the set1 and the same value from the set2 if it contains.

  • In the loop, if turn ==21, and if set2 is empty, return ‘player 1’. If the set has value, remove the first value from the set2 and the same value from the set1 if it contains.

  • Change the value of turn by turn -3 to alternate the turn.

Example

#include <iostream>
#include <vector>
#include <set>
using namespace std;

// function to find the winner
string findWinningPlayer(vector<string> arr, vector<string> brr){
   // set to store all strings
   set<string> set1(arr.begin(), arr.end());
   set<string> set2(brr.begin(), brr.end());
   // player 1 starts the game
   int turn = 1;
   // loop until the game is over
   while (true){
      // if it is player 1's turn
      if (turn == 1){
          // if player 1 has no string to remove, player 2 wins
          if (set1.empty())
              return "Player 2 won!";
          // get the first string from set 1
          auto to_remove = set1.begin();
          // remove the string from set 1
          set1.erase(set1.begin());
          // find the position of to_remove in set 2 and remove it
          auto it = set2.find(*to_remove);
          if (it != set2.end())
              set2.erase(it);
       }
       else{
          // if player 2 has no string to remove, player 1 wins
          if (set2.empty())
              return "Player 1 won!";
          // get the first string from set 2
          auto to_remove = set2.begin();
          // remove the string from set 2
          set2.erase(set2.begin());
          // find the position of to_remove in set 1 and remove it
          auto it = set1.find(*to_remove);
          if (it != set1.end())
              set1.erase(it);
      }
      turn = 3 - turn;
   }
   return ""; // should never reach this point
}
int main(){
   // Set of strings for player A
   vector<string> arr{"tuts", "point"};
   // Set of strings for player B
   vector<string> brr{"tuts", "tutorialspoint", "acd"};
   cout << findWinningPlayer(arr, brr) << endl;
   return 0;
}

Output

Player 2 won!

Time complexity – O(N + M), as we remove values from the set by taking an alternate turn.

Space complexity – O(N + M) to store array values in the set.

Updated on: 18-Aug-2023

32 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements