What I find easiest is translating the problem from a word problem into a more logical one.
Start with an empty set : [[]]
So the trick here is that this word problem tells you to create an empty set but immediately shows you a set that contains an element.
If we break this down into arrays instead(because I personally find it more intuitive) we can translate it to:
Start with an array of arrays, who's first element is an empty array. (instead of null
)
So basically
int[][] result = new int[]{ new int[0] };
Now we have somewhere to start from, we can start to translate the other parts of the word problem.
Add the First Number (1) to all existing subsets to create subsets: [[],[1]]
Add the Second Number (5) to all existing subsets ...
Add the Third Number (3) to all existing subsets ...
There's a lot of information here. Let's translate different parts
Add the 1st Number ...
Add the 2nd Number ...
Add the nth Number ...
The repetition of these instructions and the fact that each number 1, 5, 3
matches our starting set of {1, 5, 3}
tells us we should use a loop of some kind to build our result.
for(int i = 0; i < set.Length; i++)
{
int number = set[i];
// add subsets some how
}
Add the number to all existing subsets to create subsets: [[],[1]
A couple things here stand out. Notice they used the word Add but provide you an example where the number wasn't added to one of the existing subsets [[]]
turned into [[],[1]]
. Why is one of them still empty if we added 1
to all of them?
The reason for this is because when we create the new subsets and all their variations, we want to keep the old ones. So we do add the 1
to []
(the first element) but we make a copy of []
first. That way when we add 1
to that copy, we still have the original []
and now a brand new [1]
then we can combine them to create [[],[1]]
.
Using these clues we can decipher that Add the number to all existing subsets, actually means make copies of all existing subsets, add the number to each of the copies, then add those copies at the end of the result array.
int[][] result = new int[]{ new int[0] };
int[] copy = result[0];
copy.Append(1); // pseudo code
result.Append(copy); // pseudo code
// result: [[],[1]]
Let's put each of those pieces together and put together the final solution, hopefully!
Here's an example that I threw together that works(at least according to your example data).
object[] set = { 1, 5, 3 };
// [null]
object[][] result = Array.Empty<object[]>();
// add a [] to the [null] creating [[]]
Append(ref result, Array.Empty<object>());
// create a method so we can add things to the end of an array
void Append<T>(ref T[] array, T SubArrayToAdd)
{
int size = array.Length;
Array.Resize(ref array, size + 1);
array[size] = SubArrayToAdd;
}
// create a method that goes through all the existing subsets and copies them, adds the item, and adds those copies to the result array
void AddSubsets(object item)
{
// store the length of the result because if we don't we will infinitely expand(because we resize the array)
int currentLength = result.Length;
for (int i = 0; i < currentLength; i++)
{
// copy the array so we don't change the original
object[] previousItemArray = result[i]; // []
// add the item to it
Append(ref previousItemArray, item); // [1]
// add that copy to the results
Append(ref result, previousItemArray); // [[]] -> [[],[1]]
}
}
// Loop over the set and add the subsets to the result
for (int i = 0; i < set.Length; i++)
{
object item = set[i];
AddSubsets(item);
}