Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an integer n representing the length of an unknown array that you are trying to recover. You are also given an array sums containing the values of all 2n subset sums of the unknown array (in no particular order).
Return the array ans of length n representing the unknown array. If multiple answers exist, return any of them.
An array sub is a subset of an array arr if sub can be obtained from arr by deleting some (possibly zero or all) elements of arr. The sum of the elements in sub is one possible subset sum of arr. The sum of an empty array is considered to be 0.
Note: Test cases are generated such that there will always be at least one correct answer.
Example 1:
Input: n = 3, sums = [-3,-2,-1,0,0,1,2,3] Output: [1,2,-3] Explanation: [1,2,-3] is able to achieve the given subset sums: - []: sum is 0 - [1]: sum is 1 - [2]: sum is 2 - [1,2]: sum is 3 - [-3]: sum is -3 - [1,-3]: sum is -2 - [2,-3]: sum is -1 - [1,2,-3]: sum is 0 Note that any permutation of [1,2,-3] and also any permutation of [-1,-2,3] will also be accepted.
Example 2:
Input: n = 2, sums = [0,0,0,0] Output: [0,0] Explanation: The only correct answer is [0,0].
Example 3:
Input: n = 4, sums = [0,0,5,5,4,-1,4,9,9,-1,4,3,4,8,3,8] Output: [0,-1,4,5] Explanation: [0,-1,4,5] is able to achieve the given subset sums.
Constraints:
1 <= n <= 15sums.length == 2n-104 <= sums[i] <= 104Problem summary: You are given an integer n representing the length of an unknown array that you are trying to recover. You are also given an array sums containing the values of all 2n subset sums of the unknown array (in no particular order). Return the array ans of length n representing the unknown array. If multiple answers exist, return any of them. An array sub is a subset of an array arr if sub can be obtained from arr by deleting some (possibly zero or all) elements of arr. The sum of the elements in sub is one possible subset sum of arr. The sum of an empty array is considered to be 0. Note: Test cases are generated such that there will always be at least one correct answer.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
3 [-3,-2,-1,0,0,1,2,3]
2 [0,0,0,0]
4 [0,0,5,5,4,-1,4,9,9,-1,4,3,4,8,3,8]
subsets)subsets-ii)recover-the-original-array)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1982: Find Array Given Subset Sums
class Solution {
public int[] recoverArray(int n, int[] sums) {
int m = 1 << 30;
for (int x : sums) {
m = Math.min(m, x);
}
m = -m;
TreeMap<Integer, Integer> tm = new TreeMap<>();
for (int x : sums) {
tm.merge(x + m, 1, Integer::sum);
}
int[] ans = new int[n];
if (tm.merge(0, -1, Integer::sum) == 0) {
tm.remove(0);
}
ans[0] = tm.firstKey();
for (int i = 1; i < n; ++i) {
for (int j = 0; j < 1 << i; ++j) {
if ((j >> (i - 1) & 1) == 1) {
int s = 0;
for (int k = 0; k < i; ++k) {
if (((j >> k) & 1) == 1) {
s += ans[k];
}
}
if (tm.merge(s, -1, Integer::sum) == 0) {
tm.remove(s);
}
}
}
ans[i] = tm.firstKey();
}
for (int i = 0; i < 1 << n; ++i) {
int s = 0;
for (int j = 0; j < n; ++j) {
if (((i >> j) & 1) == 1) {
s += ans[j];
}
}
if (s == m) {
for (int j = 0; j < n; ++j) {
if (((i >> j) & 1) == 1) {
ans[j] *= -1;
}
}
break;
}
}
return ans;
}
}
// Accepted solution for LeetCode #1982: Find Array Given Subset Sums
func recoverArray(n int, sums []int) []int {
m := -slices.Min(sums)
rbt := redblacktree.NewWithIntComparator()
merge := func(key int, value int) {
if v, ok := rbt.Get(key); ok {
nxt := v.(int) + value
if nxt == 0 {
rbt.Remove(key)
} else {
rbt.Put(key, nxt)
}
} else {
rbt.Put(key, value)
}
}
for _, x := range sums {
merge(x+m, 1)
}
ans := make([]int, n)
merge(ans[0], -1)
ans[0] = rbt.Left().Key.(int)
for i := 1; i < n; i++ {
for j := 0; j < 1<<i; j++ {
if j>>(i-1)&1 == 1 {
s := 0
for k := 0; k < i; k++ {
if j>>k&1 == 1 {
s += ans[k]
}
}
merge(s, -1)
}
}
ans[i] = rbt.Left().Key.(int)
}
for i := 0; i < 1<<n; i++ {
s := 0
for j := 0; j < n; j++ {
if i>>j&1 == 1 {
s += ans[j]
}
}
if s == m {
for j := 0; j < n; j++ {
if i>>j&1 == 1 {
ans[j] = -ans[j]
}
}
break
}
}
return ans
}
# Accepted solution for LeetCode #1982: Find Array Given Subset Sums
class Solution:
def recoverArray(self, n: int, sums: List[int]) -> List[int]:
m = -min(sums)
sl = SortedList(x + m for x in sums)
sl.remove(0)
ans = [sl[0]]
for i in range(1, n):
for j in range(1 << i):
if j >> (i - 1) & 1:
s = sum(ans[k] for k in range(i) if j >> k & 1)
sl.remove(s)
ans.append(sl[0])
for i in range(1 << n):
s = sum(ans[j] for j in range(n) if i >> j & 1)
if s == m:
for j in range(n):
if i >> j & 1:
ans[j] *= -1
break
return ans
// Accepted solution for LeetCode #1982: Find Array Given Subset Sums
/**
* [1982] Find Array Given Subset Sums
*
* You are given an integer n representing the length of an unknown array that you are trying to recover. You are also given an array sums containing the values of all 2^n subset sums of the unknown array (in no particular order).
* Return the array ans of length n representing the unknown array. If multiple answers exist, return any of them.
* An array sub is a subset of an array arr if sub can be obtained from arr by deleting some (possibly zero or all) elements of arr. The sum of the elements in sub is one possible subset sum of arr. The sum of an empty array is considered to be 0.
* Note: Test cases are generated such that there will always be at least one correct answer.
*
* Example 1:
*
* Input: n = 3, sums = [-3,-2,-1,0,0,1,2,3]
* Output: [1,2,-3]
* Explanation: [1,2,-3] is able to achieve the given subset sums:
* - []: sum is 0
* - [1]: sum is 1
* - [2]: sum is 2
* - [1,2]: sum is 3
* - [-3]: sum is -3
* - [1,-3]: sum is -2
* - [2,-3]: sum is -1
* - [1,2,-3]: sum is 0
* Note that any permutation of [1,2,-3] and also any permutation of [-1,-2,3] will also be accepted.
*
* Example 2:
*
* Input: n = 2, sums = [0,0,0,0]
* Output: [0,0]
* Explanation: The only correct answer is [0,0].
*
* Example 3:
*
* Input: n = 4, sums = [0,0,5,5,4,-1,4,9,9,-1,4,3,4,8,3,8]
* Output: [0,-1,4,5]
* Explanation: [0,-1,4,5] is able to achieve the given subset sums.
*
*
* Constraints:
*
* 1 <= n <= 15
* sums.length == 2^n
* -10^4 <= sums[i] <= 10^4
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/find-array-given-subset-sums/
// discuss: https://leetcode.com/problems/find-array-given-subset-sums/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
pub fn recover_array(n: i32, sums: Vec<i32>) -> Vec<i32> {
vec![]
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_1982_example_1() {
let n = 3;
let sums = vec![-3, -2, -1, 0, 0, 1, 2, 3];
let result = vec![1, 2, -3];
assert_eq!(Solution::recover_array(n, sums), result);
}
#[test]
#[ignore]
fn test_1982_example_2() {
let n = 2;
let sums = vec![0, 0, 0, 0];
let result = vec![0, 0];
assert_eq!(Solution::recover_array(n, sums), result);
}
#[test]
#[ignore]
fn test_1982_example_3() {
let n = 4;
let sums = vec![0, 0, 5, 5, 4, -1, 4, 9, 9, -1, 4, 3, 4, 8, 3, 8];
let result = vec![0, -1, 4, 5];
assert_eq!(Solution::recover_array(n, sums), result);
}
}
// Accepted solution for LeetCode #1982: Find Array Given Subset Sums
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #1982: Find Array Given Subset Sums
// class Solution {
// public int[] recoverArray(int n, int[] sums) {
// int m = 1 << 30;
// for (int x : sums) {
// m = Math.min(m, x);
// }
// m = -m;
// TreeMap<Integer, Integer> tm = new TreeMap<>();
// for (int x : sums) {
// tm.merge(x + m, 1, Integer::sum);
// }
// int[] ans = new int[n];
// if (tm.merge(0, -1, Integer::sum) == 0) {
// tm.remove(0);
// }
// ans[0] = tm.firstKey();
// for (int i = 1; i < n; ++i) {
// for (int j = 0; j < 1 << i; ++j) {
// if ((j >> (i - 1) & 1) == 1) {
// int s = 0;
// for (int k = 0; k < i; ++k) {
// if (((j >> k) & 1) == 1) {
// s += ans[k];
// }
// }
// if (tm.merge(s, -1, Integer::sum) == 0) {
// tm.remove(s);
// }
// }
// }
// ans[i] = tm.firstKey();
// }
// for (int i = 0; i < 1 << n; ++i) {
// int s = 0;
// for (int j = 0; j < n; ++j) {
// if (((i >> j) & 1) == 1) {
// s += ans[j];
// }
// }
// if (s == m) {
// for (int j = 0; j < n; ++j) {
// if (((i >> j) & 1) == 1) {
// ans[j] *= -1;
// }
// }
// break;
// }
// }
// return ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.