1. Recursive Minimax Tree
Intuition
Recursively explore both choices (first and last coin), assuming the opponent plays to minimize our gain.
Algorithm
- Define
solve(i, j). - If
i > j, return 0. - If
i == j, returnarr[i]. - If
i + 1 == j, returnmax(arr[i], arr[j]). - Pick
arr[i]:val1 = arr[i] + min(solve(i+2, j), solve(i+1, j-1)). - Pick
arr[j]:val2 = arr[j] + min(solve(i+1, j-1), solve(i, j-2)). - Return
max(val1, val2).
#include <iostream>#include <vector>#include <algorithm> using namespace std; class Solution { int solve(int i, int j, const vector<int>& arr) { if (i > j) return 0; if (i == j) return arr[i]; if (i + 1 == j) return max(arr[i], arr[j]); int takeLeft = arr[i] + min(solve(i + 2, j, arr), solve(i + 1, j - 1, arr)); int takeRight = arr[j] + min(solve(i + 1, j - 1, arr), solve(i, j - 2, arr)); return max(takeLeft, takeRight); }public: int maximumAmount(vector<int>& arr, int n) { return solve(0, n - 1, arr); }}; int main() { Solution sol; vector<int> arr = {5, 3, 7, 10}; cout << "Max Amount: " << sol.maximumAmount(arr, 4) << endl; return 0;}Time & Space Complexity
- Time complexity:
O(2^n) - Space complexity:
O(n) call stack