3

I have been pondering over this problem quite some time and for some reason it is not getting through my head. If i am given an array [1,2,3,4] and a destination value of say 5. I want to get all possible combinations from the array such that they add to the destination value.

So one approach i can think of is

1!=5
1+2!=5
1+3!=5
1+4=5
//now check with combos of 3 digits.
1+2+3 !=5
1+2+4 !=5
//now check with combos of 4...however at this point i realized i missed the combination 1+3+4 also.

I have seen a few answers online but they do not seem to make sense and i am not really interested in others answers or codes, i want to learn how to think the correct way so i can solve such problems. i was wondering if someone can guide me and help me break down this problem and also how i should be thinking to solve such problems. I am not really worried by efficiency at this point because i have not even been able to formulate an approach so all approaches are welcome. Also i prefer using just array and normal loops not any other data structures like hash as i have not learned those yet.

user1010101
  • 2,062
  • 7
  • 47
  • 76
  • 4
    You probably want to enumerate all "subsets" of your original array and check which of them sums to 5. – phimuemue Sep 12 '14 at 15:09
  • @phimuemue can you elaborate? i am not quite sure what you mean. – user1010101 Sep 12 '14 at 15:11
  • Maybe this helps: http://stackoverflow.com/questions/18305843/find-all-subsets-that-sum-to-a-particular-value – phimuemue Sep 12 '14 at 15:13
  • @user2733436: Understanding the language of set theory (sets, subsets, unions, intersections etc.) is critical for thinking about algorithms like this. I suggest finding an introduction online or in a maths textbook. Luckily, there isn't much to learn :) – j_random_hacker Sep 12 '14 at 15:28
  • @j_random_hacker thanks for the tip, is it possible for you to help me find an approach or get me started in the right direction for this particular problem? – user1010101 Sep 12 '14 at 15:30
  • 1
    When approaching a problem like this, it is also helpful to think about how you can manipulate the data to make the problem easier. For example, this problem is much easier solved when the array of numbers is sorted in ascending order vs. random order. Recursion is also useful in these types of problems that break a large set into smaller sets. – Dan Harms Sep 12 '14 at 16:51
  • @dcharms yeah i would sort the array, but i was wondering if you can possibly breakdown the recursion approach for this as its going over my head. – user1010101 Sep 12 '14 at 16:53

1 Answers1

1

Since you said you want 'ways of thinking', this is one way.

You start with simplest of cases by making various assumptions

1) Assume all your array elements are smaller than the destination value. -- a simple validation will help when implementation is done.

High level steps

You need to find out a way of obtaining all possible permutations of the number.

And then add each element of the permutation and check if the sum matches 'destination' (This is simpler task)

now coming to the major challenge here:

how to obtain all possible permutations?

Solution Approach Lets assume we have an array of single element: SOlution is obvious :)

Next we have an array of two elements: You determine the size of the array: 2 You have to iterate over this size because your combinations will be less than or equal to this size. Your first iteration will have value 1. ie. you are looking for combinations of size one This is simple: you iterate over the array one by one.

Next iteration will look for combinations of size 2. Since the iteration value (2) is equal to size of the array (2), you know there is just one possible case.

Now lets handle an array of size 3:

for size 1 permutations, you know what to do.

for size 3 permutations, you know what the combination is.

for size 2 permutations, you require another iteration. you iterate over the array, hold the current element of the array and permutate rest of the array of size 2.

Next you iterate over second and then third element, and permutate rest of the array of size (3-1 = 2)

--------------------------------UPDATED--------------------------------------------------

Next lets try an array having 4 elements Lets call is A(4)

For size 1 permutations and size 4 permutations, its obvious.

For size 3 permutations, you will repeat process of what you did for obtaining size 2 permutations for an array of size 3. You will hold one element, you will be left with an array of size 3. Let call it A(3)

But remember, you also need permutations of size 2. You can determine all permutations of size 2 from this array of size 3 itself by applying the same reusable component. This becomes a recursive call.

So essentially, you have to do one thing most of the time.

'If you have an Array of size n; A(n), you need to iterate through it, hold element being iterated and you will have an array of size n-1; A(n-1)'

then make a recursive call again. and replace n with n-1 in the bold line

So essentially as you see this is turning into a recursive problem.

This is one way of thinking a solution of this problem. I hope I was clear in explaining the thinking process.

------------------------------------------Example------------------------------------------

Assume we have an array {1,2,3,4,5}

and our function looks like

 function G (int[] array ) {
   Looping over array{ 
       remove array[index] from array
        you are left with restOfTheArray .// store it some where.
       then
          make a recursive call to G with restOfTheArray; 
     }
 }

Dry run for the loop:

 Dry run 1:
  funtion G (Array (n ) ) {
    Looping over {1,2,3,4,5}{ 
        first value while looping is 1, remove it from the array;
        you have {2,3,4,5}.// store it some where.
       then
          make a recursive call to G with {2,3,4,5}
     }
 } 


  Dry run 2: 
funtion G (Array (n ) ) {
   Looping over {1,2,3,4,5}{ 
       second value while looping is 2, remove it from the array;
        you have {1,3,4,5}.// store it some where.
       then
          make a recursive call to G with {1,3,4,5}
     }
 }

and so on...

now lets look at the dry run of the recursive call:

  Dry Run 1.1
 funtion G (Array (n ) ) {
   Looping over {1,2,3,4,5}{ 
       First value while looping is 1, remove it from the array;
        you have {2,3,4,5}.// store it some where.
       then
          make a recursive call to G with {2,3,4,5}
     }
 }

 Dry Run 1.2 

 funtion G (Array (n ) ) {
   Looping over {2,3,4,5}{ 
       First value while looping is 2, remove it from the array;
        you have {3,4,5}.// store it some where.
       then
          make a recursive call to G with {3,4,5}
     }
 }

and so on...

BenMorel
  • 34,448
  • 50
  • 182
  • 322
DolphinJava
  • 2,682
  • 1
  • 23
  • 37
  • I don't get why you make assumptions in the beginning such as fixed element size and also that the array values are samller than destination value – user1010101 Sep 12 '14 at 16:27
  • Sorry for confusing that. I came up with solution on the go. I started by simplifying the problem in mind so that my thinking does not gets blocked. :) – DolphinJava Sep 12 '14 at 16:28
  • I edited the assumptions. Basically the idea regarding assumptions is that when beginning to solve a problem, its sometimes a good idea to assume few things so that one can narrow focus down to the core part of the problem. Resolve it and then one by one remove assumptions and keep amending the solution. – DolphinJava Sep 12 '14 at 16:31
  • np! so i assume your answer should be read from the solution approach... i am still kind of unclear as to how this works recursively – user1010101 Sep 12 '14 at 16:31
  • I clarified the recursive part in the answer. Please have a look again at the answer now. – DolphinJava Sep 12 '14 at 16:49
  • i am sorry will it be possible to show visuals like i get lost what u mean by iterating over size of array – user1010101 Sep 12 '14 at 17:05
  • @user2733436 Added visuals as part of dry run. – DolphinJava Sep 12 '14 at 17:19
  • That helps quite a bit so now i get that u take out one index and keep making recursive calls but how will this make sure all combinations are printed – user1010101 Sep 12 '14 at 17:24
  • Continue with the dry run of the loop and the recursiveness. Try it out for a small sample. see it for yourself. If this answers your queries, kindly accept the answer. – DolphinJava Sep 12 '14 at 17:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/61131/discussion-between-user2733436-and-dolphinjava). – user1010101 Sep 12 '14 at 18:23
  • when you say remove the first index and store the rest of the array somewhere what does this do? why are we storing the rest of array? – user1010101 Sep 12 '14 at 18:28
  • Each array is a permutation. The arrays that you are storing, will give you a permutation. Add the elements of the array to check if sum is equal to your destination number. For eg: for an array {1,3,4,5}; add its elements 1+3+4+5 – DolphinJava Sep 12 '14 at 18:31