You are given an integer array nums. Your task is to remove all elements from the array by performing one of the following operations at each step until nums is empty:
Choose any two elements from the first three elements of nums and remove them. The cost of this operation is the maximum of the two elements removed.
If fewer than three elements remain in nums, remove all the remaining elements in a single operation. The cost of this operation is the maximum of the remaining elements.
Return the minimum cost required to remove all the elements.
Input: nums =[6,2,8,4]Output: 12Explanation:
Initially,`nums = [6, 2, 8, 4]`.* In the first operation, remove `nums[0] = 6` and `nums[2] = 8`with a cost of `max(6, 8) = 8`. Now,`nums = [2, 4]`.* In the second operation, remove the remaining elements with a cost of `max(2, 4) = 4`.The cost to remove all elements is`8 + 4 = 12`. This is the minimum cost to
remove all elements in`nums`. Hence, the output is12.
Input: nums =[2,1,3,3]Output: 5Explanation:
Initially,`nums = [2, 1, 3, 3]`.* In the first operation, remove `nums[0] = 2` and `nums[1] = 1`with a cost of `max(2, 1) = 2`. Now,`nums = [3, 3]`.* In the second operation remove the remaining elements with a cost of `max(3, 3) = 3`.The cost to remove all elements is`2 + 3 = 5`. This is the minimum cost to
remove all elements in`nums`. Hence, the output is5.
At each step, we can remove any two of the first three elements, paying the maximum of the two, or if fewer than three remain, remove all at once. This is a classic DP problem where the state is the current array. Since the array can be up to 16 elements (as per LeetCode constraints), we can use memoization (tuple or bitmask) to cache results.
classSolution {
funminCost(nums: IntArray): Int {
val memo = mutableMapOf<String, Int>()
fundp(arr: IntArray, n: Int): Int {
if (n <=2) returnif (n ==0) 0else arr.maxOrNull()!!val key = arr.copyOf(n).joinToString(",")
if (key in memo) return memo[key]!!var res = Int.MAX_VALUE
for (i in0 until 3) {
for (j in i+1 until 3) {
val nxt = arr.filterIndexed { idx, _ -> idx != i && idx != j }.toIntArray()
res = minOf(res, maxOf(arr[i], arr[j]) + dp(nxt, n-2))
}
}
memo[key] = res
return res
}
return dp(nums, nums.size)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
defminCost(self, nums: list[int]) -> int:
from functools import lru_cache
n = len(nums)
@lru_cache(None)
defdp(state: tuple) -> int:
arr = list(state)
if len(arr) <=2:
return max(arr) if arr else0 res = float('inf')
for i in range(3):
for j in range(i+1, 3):
nxt = tuple(arr[k] for k in range(len(arr)) if k != i and k != j)
res = min(res, max(arr[i], arr[j]) + dp(nxt))
return res
return dp(tuple(nums))
⏰ Time complexity: O(3^n), where n is the length of nums. Each state branches up to 3 choose 2 = 3 ways, but memoization prunes repeated states. For n up to 16, this is feasible.
🧺 Space complexity: O(3^n), for memoization cache.