All combinations (again...) for a Google problem

Daily Coding Problem:

This problem was asked by Google.
Given a list of integers S and a target number k, write a function that returns a subset of S that adds up to k. If such a subset cannot be made, then return null.
Integers can appear more than once in the list. You may assume all numbers in the list are positive.
For example, given S = [12, 1, 61, 5, 9, 2] and k = 24, return [12, 9, 2, 1] since it sums up to 24.

I'm sure there is a more efficient solution, but I decided to implement an all combinations brute-force approach:
 - Have a base case
 - Control the code with an index i
 - Either don't add s[i] and move along
 - Or add s[i] and move along
 - Found the very first solution? Bail

Seems to work, but 2^n:


Code is in github: https://github.com/marcelodebarros/dailycodingproblem/blob/master/DailyCodingProblem10262018.cs

And here:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace DailyCodingProblem
{
 class DailyCodingProblem10262018
 {
  public int[] FindSubsetAddsToTarget(int[] set, int target)
  {
   LinkedList subset = new LinkedList();
   int[] retVal = null;
   FindSubsetAddsToTarget(set, 0, subset, ref retVal, 0, target);
   return retVal;
  }

  private bool FindSubsetAddsToTarget(int[] set,
           int currentIndex,
           LinkedList subset,
           ref int[] retVal,
           int currentSum,
           int target)
  {
   //Base
   if (currentSum == target && subset.Count > 0)
   {
    retVal = subset.ToArray();
    return true;
   }
   if (currentIndex >= set.Length) return false;

   //Don't add
   if (FindSubsetAddsToTarget(set, currentIndex + 1, subset, ref retVal, currentSum, target)) return true;

   //Add
   subset.AddLast(set[currentIndex]);
   if (FindSubsetAddsToTarget(set, currentIndex + 1, subset, ref retVal, currentSum + set[currentIndex], target)) return true;
   subset.RemoveLast();

   return false;
  }
 }
}

Comments

  1. Tried a solution using Dynamic Programming :)
    I believe complexity would be : O(sum * n)

    using System;

    class subsetSumDP
    {
    static bool isSubsetSum(int []arr, int n, int sum)
    {
    bool [,]arrSub = new bool[sum+1,n+1];

    for (int i = 0; i <= n; i++)
    arrSub[0, i] = true;

    for (int i = 1; i <= sum; i++)
    arrSub[i, 0] = false;

    for (int i = 1; i <= sum; i++)
    {
    for (int j = 1; j <= n; j++)
    {
    arrSub[i, j] = arrSub[i, j - 1];
    if (i >= arr[j - 1])
    arrSub[i, j] = arrSub[i, j] ||
    arrSub[i - set[j - 1], j - 1];

    }
    }

    return arrSub[sum,n];
    }

    public static void Main ()
    {
    // random array
    int []arr = {1, 6, 6, 3, 5};
    int sum = 9;
    int n = arr.Length;
    if (isSubsetSum(arr, n, sum) == true)
    Console.WriteLine("Woohoo found a subset ");
    else
    Console.WriteLine("Nah no subset");
    }
    }

    ReplyDelete

Post a Comment

Popular posts from this blog

Advent of Code - Day 6, 2024: BFS and FSM

Golang vs. C#: performance characteristics (simple case study)

Advent of Code - Day 7, 2024: Backtracking and Eval