1. Naive 4-Way Recursion (Without Sorting Pruning)
Intuition
Maintain sides[4]. For matchstick idx, try placing into sides 0, 1, 2, and 3. If side sum exceeds sideLen, backtrack. When all matchsticks are placed, check if all 4 sides equal sideLen.
When to apply: Baseline comparison demonstrating severe worst-case timeout on unoptimized backtracking.
Algorithm
- If
totalSum % 4 != 0, return false. - Set
target = totalSum / 4. - In
solve(idx): - - If
idx == matchsticks.length, returnsides[0] == target && .... - - For each side
jfrom 0 to 3: - - If
sides[j] + matchsticks[idx] <= target: - -
sides[j] += matchsticks[idx]. - - If
solve(idx + 1)returns true, return true. - -
sides[j] -= matchsticks[idx]. - - Return false.
#include <iostream>#include <vector>#include <numeric> using namespace std; class Solution { bool solve(int idx, int target, const vector<int>& matchsticks, vector<int>& sides) { if (idx == matchsticks.size()) { return sides[0] == target && sides[1] == target && sides[2] == target && sides[3] == target; } for (int j = 0; j < 4; j++) { if (sides[j] + matchsticks[idx] <= target) { sides[j] += matchsticks[idx]; if (solve(idx + 1, target, matchsticks, sides)) return true; sides[j] -= matchsticks[idx]; } } return false; } public: bool makesquare(vector<int>& matchsticks) { long long sum = accumulate(matchsticks.begin(), matchsticks.end(), 0LL); if (sum % 4 != 0 || matchsticks.size() < 4) return false; int target = sum / 4; vector<int> sides(4, 0); return solve(0, target, matchsticks, sides); }}; int main() { Solution sol; vector<int> sticks = {1, 1, 2, 2, 2}; cout << (sol.makesquare(sticks) ? "true" : "false") << endl; return 0;}Time & Space Complexity
- Time complexity:
O(4^N)— Branches 4 ways for each of the N matchsticks without pruning. - Space complexity:
O(N)— Recursion depth is N.