🧠
Brute Force (Exhaustive Search with Recursion)
💡 This approach tries all possible transformations on each element to find the minimal deviation. It is impractical for large inputs but helps understand the problem deeply.
Intuition
Try every possible combination of doubling odd numbers and halving even numbers recursively, then compute the deviation for each combination to find the minimum.
Algorithm
- Define a recursive function that tries all valid transformations on each element.
- At each recursion level, transform the current element if possible and recurse to the next.
- Keep track of the minimum and maximum elements in the current array state.
- Return the minimum deviation found after exploring all transformations.
💡 The recursion tree grows exponentially, making it hard to visualize and inefficient, but it guarantees correctness by exploring all states.
from math import inf
def min_deviation_brute(nums):
n = len(nums)
min_dev = inf
def dfs(i, arr):
nonlocal min_dev
if i == n:
current_dev = max(arr) - min(arr)
if current_dev < min_dev:
min_dev = current_dev
return
val = arr[i]
# Try without change
dfs(i + 1, arr)
# If even, try halving
if val % 2 == 0:
arr[i] = val // 2
dfs(i + 1, arr)
arr[i] = val
# If odd, try doubling
if val % 2 == 1:
arr[i] = val * 2
dfs(i + 1, arr)
arr[i] = val
dfs(0, nums[:])
return min_dev
# Driver code
if __name__ == '__main__':
print(min_deviation_brute([1,2,3,4])) # Expected output: 1
Line Notes
def dfs(i, arr):Defines recursive function to explore transformations at index i
if i == n:Base case: all elements processed, compute deviation
dfs(i + 1, arr)Recurse without changing current element
if val % 2 == 0:If even, try halving to explore that transformation
import java.util.*;
public class MinDeviationBrute {
static int minDev = Integer.MAX_VALUE;
static int n;
public static void dfs(int i, int[] arr) {
if (i == n) {
int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
for (int val : arr) {
max = Math.max(max, val);
min = Math.min(min, val);
}
minDev = Math.min(minDev, max - min);
return;
}
int val = arr[i];
// Without change
dfs(i + 1, arr);
// If even, try halving
if (val % 2 == 0) {
arr[i] = val / 2;
dfs(i + 1, arr);
arr[i] = val;
}
// If odd, try doubling
if (val % 2 == 1) {
arr[i] = val * 2;
dfs(i + 1, arr);
arr[i] = val;
}
}
public static int minimumDeviation(int[] nums) {
n = nums.length;
dfs(0, nums);
return minDev;
}
public static void main(String[] args) {
System.out.println(minimumDeviation(new int[]{1,2,3,4})); // Expected: 1
}
}
Line Notes
public static void dfs(int i, int[] arr)Recursive function exploring transformations at index i
if (i == n)Base case: all elements processed, compute deviation
dfs(i + 1, arr);Recurse without changing current element
if (val % 2 == 0)Try halving if element is even
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int minDev = INT_MAX;
int n;
void dfs(int i, vector<int>& arr) {
if (i == n) {
int maxVal = INT_MIN, minVal = INT_MAX;
for (int val : arr) {
maxVal = max(maxVal, val);
minVal = min(minVal, val);
}
minDev = min(minDev, maxVal - minVal);
return;
}
int val = arr[i];
// Without change
dfs(i + 1, arr);
// If even, try halving
if (val % 2 == 0) {
arr[i] = val / 2;
dfs(i + 1, arr);
arr[i] = val;
}
// If odd, try doubling
if (val % 2 == 1) {
arr[i] = val * 2;
dfs(i + 1, arr);
arr[i] = val;
}
}
int minimumDeviation(vector<int>& nums) {
n = nums.size();
dfs(0, nums);
return minDev;
}
int main() {
vector<int> nums = {1,2,3,4};
cout << minimumDeviation(nums) << endl; // Expected: 1
return 0;
}
Line Notes
void dfs(int i, vector<int>& arr)Recursive function exploring all transformations at index i
if (i == n)Base case: all elements processed, compute deviation
dfs(i + 1, arr);Recurse without changing current element
if (val % 2 == 0)Try halving if element is even
function minimumDeviation(nums) {
let minDev = Infinity;
const n = nums.length;
function dfs(i, arr) {
if (i === n) {
const maxVal = Math.max(...arr);
const minVal = Math.min(...arr);
minDev = Math.min(minDev, maxVal - minVal);
return;
}
const val = arr[i];
// Without change
dfs(i + 1, arr);
// If even, try halving
if (val % 2 === 0) {
arr[i] = val / 2;
dfs(i + 1, arr);
arr[i] = val;
}
// If odd, try doubling
if (val % 2 === 1) {
arr[i] = val * 2;
dfs(i + 1, arr);
arr[i] = val;
}
}
dfs(0, nums.slice());
return minDev;
}
// Test
console.log(minimumDeviation([1,2,3,4])); // Expected: 1
Line Notes
function dfs(i, arr)Recursive helper to explore transformations at index i
if (i === n)Base case: all elements processed, compute deviation
dfs(i + 1, arr);Recurse without changing current element
if (val % 2 === 0)Try halving if element is even
TimeO(2^n)
SpaceO(n) recursion stack
Each element can be transformed in up to two ways, leading to exponential combinations.
💡 For n=20, this means over a million combinations, which is too large to run in reasonable time.
Interview Verdict: TLE
This approach is too slow for large inputs but is useful to understand the problem and correctness.