Table of contents
1.
Introduction
2.
Problem Statement:
3.
Explanation of the Problem Statement:
4.
 Solution:
5.
Recursive Solution:
5.1.
Algorithm for the Recursive Solution:
5.2.
Code for the Recursive Solution:
6.
Top-Down Approach:
6.1.
Algorithm for the Top-Down  Solution:
6.2.
Code for the Top-Down Approach:
7.
Bottom-Up Approach:
7.1.
Algorithm for the Bottom-Up Solution:
7.2.
Code for the Bottom-Up Approach:
8.
Space Optimization:
8.1.
Algorithm for the Space Optimization:
8.2.
Code for the Space Optimization:
9.
Frequently Asked Question:
10.
Key TakeAway:
Last Updated: Mar 27, 2024

Stone Game III

Author Yogesh Kumar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Today’s problem, i.e., –Stone Game III,” is highly asked in product-based companies like Amazon, Google, and Microsoft.

We’ll go over all the methods, including brute force and the most efficient way to solve this problem.

We are going to solve one of the problems of Leetcode by a different approach.

 

Problem Statement:

Alice and Bob continue their games with piles of stones. Several stones are arranged in a row, and each stone has an associated value, an integer given in the array stoneValue.

Alice and Bob take turns, with Alice starting first. On each player's turn, that player can take 1, 2, or 3 stones from the first remaining stones in the row.

The score of each player is the sum of the values of the stones taken. The score of each player is 0 initially.

The game’s objective is to end with the highest score, and the winner is the player with the highest score, and there could be a tie. The game continues until all the stones have been taken.

Assume Alice and Bob play optimally.

Return "Alice" if Alice will win, "Bob" if Bob will win, or "Tie" if they end the game with the same score. Eg: - values=[1,2,3,7]

Output: “Bob”  As Alice’s best move is only taking three stones at the same time, and, i.e., also less than seven so Bob is a winner in all aspects.

Explanation of the Problem Statement:

In this problem, there are two-player playing the game with piles of stones. Both the players will have to turn one by one. 

 

Important Information in Question: 

  1. Two players are playing the pile of stone, i.e., Alice and Bob.
  2. Each player’s turn comes one by one.
  3. Alice will be the first player to start the game.
  4. On each turn, each player has the choice of taking 1,2 or 3 stones from the remaining.
  5. The initial score of both the players is initially 0.
  6. The score is counted upon how many stones are handled by each player.
  7. Winner of the game decides upon the highest number of the stone which player has.
  8. The game will continue to be played until a single stone is present.
  9. If, in the end, both have the same number of rocks, then the game is tied.
  10. If Alice won, return “Alice” if Bob won return “Bob” else return “Tie.”

 

Now Take an Example To understand the Approach To deal with the Question:-

 

Eg: stoneValue =[ 1 , 2 , 3, 7 ]

 

[ 1 , 2 , 3, 7 ]

          I

1    [ 2, 3, 7 ] [ 1, 2](3)   [3 , 7]    [ 1, 2, 3](6)  [7]

I         I I                      

2 [ 3, 7]      5 [7]      12  [ ]            3 [ 7 ]            10 [ ]                7 [ ]

 

Explanation of Above Representation:-   

Seeing the Above example as a stoneValue array which contains four stones having different values 1, 2, 3, and 7, and Alice starts the game in the first stage, he has three choices either go for one or [1,2] or [1,2,3] bucket size stone, similarly for the remaining part of stone left, again Bob has also three choices to choose the number of stone 1, 2 or 3. This step continues to follow till we have the number of stones left.

For solving this question.”, As we see here, we are recursion 1, 2, or 3 bucket size stone numbers present in it. In the next step, also we repeat the same, so here some recursion is pointing out for this question.

 

 Solution:

   We are going to solve the problem in an optimized solution.

   A possible solution for the Problem:-

  1. Recursive Solution
  2. Top-Down Approach
  3. Bottom-Up Approach
  4. Optimizing the Space, doing in constant Time.

  Here we are going to start with the generic solution and move to an ideal solution.

  Deciding Factor who has won the game here is the difference between the sum of no of stone value Alice  and sum of no of stone Value Bob has :

  1. If the difference is >0, until we have Alice winner as the first person to start the game is Alice.
  2. If the difference is <0, then we have Bob winning as the second person is him.
  3. If difference ==0, both Bob and Alice have the same sum of no of Stone Value.

 

Recursive Solution:

In this approach, we came with the idea for recursion. After doing one element, we move to the next element for the solution. We generally solve the problem for the next half in a similar manner, which is going till no more elements are left because of that idea of Recursion hit here. One more important point here is the base condition, which is simple: when we exceed the number of stones, then we have to return 0 because anything beyond that is meaningless to calculate.

Algorithm for the Recursive Solution:

  1. Take the “N” size of stones which has a value specified for each one.
  2. Declare the function helper for finding the solution.
  3. First, pass the stoneValue array of size N to the helper function.
  4. Now Calculate the ans when the player selects 1 stone and store the value.
  5. Now Calculate the ans when the player selects 2 or 3 stone.
  6. In each stage, when we choose stone, keep the maximum value in the answer. 
  7. At last, return the answer, with the base condition when no stone remains.
  8. Value of Answer is calculated as the sum value specified on stone for no. of stone taken at a single time.

 

 

Code for the Recursive Solution:

 

import java.util.Scanner;

public class stoneGame {
  static int help(int [] stoneValue,int id){
      int ans=Integer.MIN_VALUE;
      if(id>=stoneValue.length){
          return 0;
      }
      else{
          ans=Math.max(ans,stoneValue[id]-help(stoneValue,id+1));
          if(id+1<stoneValue.length){
              ans=Math.max(ans,stoneValue[id]+stoneValue[id+1]-help(stoneValue,id+2));
          }
          if(id+2<stoneValue.length){
              ans=Math.max(ans,stoneValue[id]+stoneValue[id+1]+stoneValue[id+2]-help(stoneValue,id+3));
          }
          return ans;
      }
  }
  public static void main(String[] args){
      Scanner sc=new Scanner(System.in);
      int n= sc.nextInt();
      int [] stoneValue=new int[n];
      for(int i=0;i<n;i++){
          stoneValue[i]= sc.nextInt();
      }
      int difference=help(stoneValue,0);
      if(difference>0){
          System.out.println("Alice");
      }
      else if(difference<0){
          System.out.println("Bob");
      }
      else {
          System.out.println("Tie");
      }
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Input:

4

1 2 3 6

 

 

 

Output:

“Tie”

 

 

Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise, she will lose.

 

Top-Down Approach:

In seeing the Recursive Approach solution, we find some of part of the sequence we are solving like [ 3, 7] because of gets we get the idea of using Dynamic Programming, as we solve the problem From Top part start storing the solution by creating an extra space of N size, in which we insert the solution and calling the function in future we make separate condition else we have a solution then we directly return that.

Algorithm for the Top-Down  Solution:

  1. We have to declare and dp array of extra “N” size as we have to store the solution. In the future, if needed, we directly find in O(1) times.
  2. All the remaining steps of the Recursive Approach are the same here.

Code for the Top-Down Approach:

 

 

import java.util.Scanner;

public class stoneGame {
  static int [] dp=new int[501];
  static int help(int [] stoneValue,int id){
      int ans=Integer.MIN_VALUE;
      if(id>=stoneValue.length){
          return 0;
      }
      if(dp[id]!=-1){
          return  dp[id];
      }
      else{
          ans=Math.max(ans,stoneValue[id]-help(stoneValue,id+1));
          if(id+1<stoneValue.length){
              ans=Math.max(ans,stoneValue[id]+stoneValue[id+1]-help(stoneValue,id+2));
          }
          if(id+2<stoneValue.length){
              ans=Math.max(ans,stoneValue[id]+stoneValue[id+1]+stoneValue[id+2]-help(stoneValue,id+3));
          }
          return dp[id]=ans;
      }
  }
  public static void main(String[] args){
      Scanner sc=new Scanner(System.in);
      int n= sc.nextInt();
      int [] stoneValue=new int[n];
      for(int i=0;i<n;i++){
          stoneValue[i]= sc.nextInt();
      }
      for(int i=0;i<stoneValue.length;i++){
          dp[i]=-1;
      }
      int difference=help(stoneValue,0);
      if(difference>0){
          System.out.println("Alice");
      }
      else if(difference<0){
          System.out.println("Bob");
      }
      else {
          System.out.println("Tie");
      }
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Input:

4

1 2 3 6

 

 

 

Output:

“Tie”

 

 

Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise, she will lose.

 

Time Complexity:  Time Complexity for the solution is O(N).

Space Complexity: O(N), because we’re taking extra space.

Bottom-Up Approach:

In Dynamic Programming, the question is solved in Bottom-Up Approach also, for that purpose, we require three values, if we are at “idx,” then we needed three values idx+1,+2,+3 respectively, moving from Bottom to Up, as we require a solution for 1, 2 or 3 no of stone.

Algorithm for the Bottom-Up Solution:

  1. We are creating a DP array of size N+1 initialized all with the value of “0”.
  2. We start iteration from the last index and continue till idx>=0.
  3. We repeat the step of Recursive Approach logic for finding the solution for taking 1, 2, or 3 no of stone and summing the value of it.
  4. After that it is its,taking the max of all 3 in the Dp array.
  5. The final answer we get from the idx=0 as we fill the max value of the solution.
  6. Then return the Winner’s name. 

Code for the Bottom-Up Approach:

 

 

import java.util.Scanner;

public class Stonegame_BUA {
  public  static  void main(String [] args){
      Scanner sc=new Scanner(System.in);
      int n= sc.nextInt();
      int [] stoneValue=new int[n];
      for(int i=0;i<n;i++){
          stoneValue[i]= sc.nextInt();
      }
      int len=stoneValue.length;
      int [] dp=new int[len+1];
      int idx=len-1;
      while (idx>=0){
          int ans=Integer.MIN_VALUE;
          ans=Math.max(ans,stoneValue[idx]-dp[idx+1]);
          if(idx+1<stoneValue.length){
              ans=Math.max(ans,stoneValue[idx]+stoneValue[idx+1]-dp[idx+2]);
          }
          if(idx+2<stoneValue.length){
              ans=Math.max(ans,stoneValue[idx]+stoneValue[idx+1]+stoneValue[idx+2]-dp[idx+3]);
          }
          dp[idx]=ans;
          idx--;
      }
      int winner=dp[0];
      if(winner>0){
          System.out.println("Alice");
      }
      else if(winner<0){
          System.out.println("Bob");
      }
      else {
          System.out.println("Tie");
      }
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Input:

4

1 2 3 6

 

 

 

Output:

“Tie”

 

 

Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise, she will lose.

 

Time Complexity: Time Complexity is also O(N) because we are filling the solution for the “idx” location and then return the solution at idx=0, in O(1).

Space Complexity: Space requires as we create an N+1 size extra array for that, so Space Complexity is O(N)

Space Optimization:

As seen above all things of solving require only three values only to fill the DP array.

For fill the dp[i] we require only dp[i+1], dp[i+2] and dp[i+3] to fill the i th position.

Similar Manner, it goes on. As for that, we require not to create the DP array of size N, this can be done by using three variables from which we get a max of all the values, and by this, we fill i the index, updating the answer at last at idx=0 we return an answer. Hence Time Complexity remains O(N), but we optimized the space here from O(N) to O(1).

 

    dp[i] dp[i+1] dp[i+2] dp[i+3] X X X

 

Algorithm for the Space Optimization:

  1. We declare three variables initially having assigned value to 0.
  2. Now find the value of the answer by taking 1, 2, a, or 3 stones, and repeat for the remaining stone.
  3. Now updating the value by Bottom-up manner for three variables.

dp_3=dp_2 , dp_2=dp_1, dp_1=ans.

4. Now repeat the step till no stone remains.

5. After that, all the stone is complete the dp_1 value will give us the answer.

6. After that, we check the condition and return the parameter.

Code for the Space Optimization:

 

 

import java.util.Scanner;

public class Stonegame_BUA {
   public  static  void main(String [] args){
       Scanner sc=new Scanner(System.in);
       int n= sc.nextInt();
       int [] stoneValue=new int[n];
       for(int i=0;i<n;i++){
           stoneValue[i]= sc.nextInt();
       }
       int len=stoneValue.length;
       int dp_1=0,dp_2=0,dp_3=0;
       int idx=len-1;
       while (idx>=0){
           int ans=Integer.MIN_VALUE;
           ans=Math.max(ans,stoneValue[idx]-dp_1);
            if(idx+1<stoneValue.length){
               ans=Math.max(ans,stoneValue[idx]+stoneValue[idx+1]-dp_2);
           }
           if(idx+2<stoneValue.length){               ans=Math.max(ans,stoneValue[idx]+stoneValue[idx+1]+stoneValue[idx+2]-dp_3);
          }
           dp_3=dp_2;
           dp_2=dp_1;
           dp_1=ans;
           idx--;
       }
      int winner=dp_1;
      if(winner>0){
          System.out.println("Alice");
      }
      else if(winner<0){
          System.out.println("Bob");
      }
      else {
          System.out.println("Tie");
      }
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Input:

4

1 2 3 6

 

 

 

Output:

“Tie”

 

 

Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise, she will lose.

 

Time Complexity: O(n), where n is the number of elements in the array.

Space Complexity: O(1) as we are not consuming any extra space.

 

Frequently Asked Question:

1). What is Recursion?

Ans: Calling the function over a defined base condition to solve the sub-task for a repeated solution.

2). What is the Best Time Complexity for the Stone Game III problem?

Ans: Time Complexity is O(N), and Space Complexity is O(1) by using Dynamic Programming and three defined variables required to do the task.

3). How do we approach the Dynamic Programming Problem?

Ans: Using Top-Down and Bottom-Up Approach.

 

Key TakeAway:

In this blog, we take a problem, understand its solution in Recursive Approach and make way for the Dynamic Programming, as repetition is occurring storing in DP array then after moving to Top-Down and Bottom-Up Approach after that seeing the constraint present in the question for taking 1, 2 or 3 stones using that declares three variable for storing the solution for each, then after using no extra space as only for constant space for the three variable. So, Therefore the Main purpose is to take a problem and optimize the solution to the best of knowledge.

Check out this problem - Frog Jump

Live masterclass