Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

293. Flip Game - Leetcode Solution

Problem Description

The Flip Game problem on Leetcode asks you to generate all possible states of a string after flipping any pair of consecutive '+' characters to '--'.

You are given a string s consisting only of the characters '+' and '-'. Your task is to return all possible strings that can be obtained by flipping any occurrence of "++" into "--" in s.

Key constraints:

  • You can only flip one pair of consecutive '+' at a time.
  • Return all possible results in any order.
  • Each flip must be a new string (do not reuse elements).
  • If no flips are possible, return an empty list.
Example:
Input: s = "++++"
Output: ["--++","+--+","++--"]

Thought Process

The core idea is to identify every pair of consecutive '+' characters in the string and flip them to '--' to create a new state.

The brute-force way would be to check every possible pair, flip it, and add the resulting string to the output. This is feasible because each flip is independent and we only need to perform one flip per result.

There is no need for recursion or backtracking, since we only flip one pair at a time. We simply scan left-to-right, and whenever we see "++", we flip it and store the new string.

Optimization isn't needed for this problem since the constraints are small, but we should be careful to only flip one pair per result and not to miss any possible flip.

Solution Approach

Let's break down the steps to solve the problem:

  1. Iterate through the string: Use a loop to check every index i from 0 to len(s) - 2.
  2. Check for consecutive pluses: At each index, check if s[i] == '+' and s[i+1] == '+' . This identifies a valid flip location.
  3. Perform the flip: Create a new string where s[i] and s[i+1] are replaced with '--', and the rest of the string remains the same.
  4. Store the result: Add the new string to a results list.
  5. Return all unique results: After the loop, return the list of all possible strings.

Justification:
  • We use a loop because each flip is independent and only one flip is allowed per result.
  • String slicing (or substring operations) is used for easy replacement of the flipped pair.
  • No extra data structures are needed as the problem is straightforward and doesn't require optimization for speed or memory.

Example Walkthrough

Let's use the input s = "++++" as an example.

Step-by-step:

  1. Start at index 0: s[0] == '+' and s[1] == '+' . Flip these to get "--++".
  2. Move to index 1: s[1] == '+' and s[2] == '+' . Flip these to get "+--+".
  3. Move to index 2: s[2] == '+' and s[3] == '+' . Flip these to get "++--".
  4. Index 3 is out of range for a pair, so we're done.

Final output: ["--++", "+--+", "++--"]

Each result comes from flipping a different pair of consecutive pluses.

Time and Space Complexity

Brute-force approach:

  • Time Complexity: O(N^2) in the worst case, where N is the length of the string. For each of the O(N) positions, creating a new string via slicing/substrings takes O(N) time.
  • Space Complexity: O(N^2) in the worst case, since we may have up to O(N) results, each of length O(N).
Optimized approach:
  • The approach described is already optimal for this problem. No further optimizations are necessary due to the problem's constraints.

Summary

The Flip Game problem is an exercise in string manipulation and careful iteration. By scanning for every pair of consecutive '+' characters and flipping them one at a time, we generate all possible next states. The solution is elegant in its simplicity: no recursion or extra data structures are needed, just a simple loop and string slicing. This makes the code easy to understand and efficient for the problem's constraints.

Code Implementation

class Solution:
    def generatePossibleNextMoves(self, s: str):
        res = []
        for i in range(len(s) - 1):
            if s[i] == '+' and s[i + 1] == '+':
                flipped = s[:i] + '--' + s[i+2:]
                res.append(flipped)
        return res
      
class Solution {
public:
    vector<string> generatePossibleNextMoves(string s) {
        vector<string> res;
        for (int i = 0; i < (int)s.size() - 1; ++i) {
            if (s[i] == '+' && s[i+1] == '+') {
                string flipped = s.substr(0, i) + "--" + s.substr(i+2);
                res.push_back(flipped);
            }
        }
        return res;
    }
};
      
class Solution {
    public List<String> generatePossibleNextMoves(String s) {
        List<String> res = new ArrayList<>();
        for (int i = 0; i < s.length() - 1; i++) {
            if (s.charAt(i) == '+' && s.charAt(i+1) == '+') {
                String flipped = s.substring(0, i) + "--" + s.substring(i+2);
                res.add(flipped);
            }
        }
        return res;
    }
}
      
/**
 * @param {string} s
 * @return {string[]}
 */
var generatePossibleNextMoves = function(s) {
    const res = [];
    for (let i = 0; i < s.length - 1; i++) {
        if (s[i] === '+' && s[i+1] === '+') {
            let flipped = s.slice(0, i) + '--' + s.slice(i+2);
            res.push(flipped);
        }
    }
    return res;
};