Tags

  • AWS (7)
  • Apigee (3)
  • ArchLinux (5)
  • Array (6)
  • Backtracking (6)
  • BinarySearch (6)
  • C++ (19)
  • CI&CD (3)
  • Calculus (2)
  • DesignPattern (43)
  • DisasterRecovery (1)
  • Docker (8)
  • DynamicProgramming (20)
  • FileSystem (11)
  • Frontend (2)
  • FunctionalProgramming (1)
  • GCP (1)
  • Gentoo (6)
  • Git (15)
  • Golang (1)
  • Graph (10)
  • GraphQL (1)
  • Hardware (1)
  • Hash (1)
  • Kafka (1)
  • LinkedList (13)
  • Linux (27)
  • Lodash (2)
  • MacOS (3)
  • Makefile (1)
  • Map (5)
  • MathHistory (1)
  • MySQL (21)
  • Neovim (10)
  • Network (66)
  • Nginx (6)
  • Node.js (33)
  • OpenGL (6)
  • PriorityQueue (1)
  • ProgrammingLanguage (9)
  • Python (10)
  • RealAnalysis (20)
  • Recursion (3)
  • Redis (1)
  • RegularExpression (1)
  • Ruby (19)
  • SQLite (1)
  • Sentry (3)
  • Set (4)
  • Shell (3)
  • SoftwareEngineering (12)
  • Sorting (2)
  • Stack (4)
  • String (2)
  • SystemDesign (13)
  • Terraform (2)
  • Tree (24)
  • Trie (2)
  • TwoPointers (16)
  • TypeScript (3)
  • Ubuntu (4)
  • Home

    [Dynamic Programming] How Sum

    Published Nov 09, 2021 [  DynamicProgramming  ]

    Problem

    Write a function howSum(targetSum, numbers) that takes in a target sum and an array of numbers as arguments.

    The function should return an array containing any combination of elements that add up to exactly the target sum. If there is no combination that adds up to the target sum, then return null.

    If there are multiple combinations possible, you may return any single one.

    Brute Force

    const howSum = (targetSum, numbers) => {
    	// base cases
    	// return different values for different base cases
    	if(targetSum === 0) return []
    	if(targetSum < 0) return null
    
    	// reduce the problem size and solve the sub problem
    	for (let num of numbers) {
    		let remainValue = targetSum - num
    		let temp = howSum(remainValue, numbers)
    		if(temp !== null) {
    			return [...temp, num]
    		}
    	}
    
    	return null
    }
    

    Memoization

    const howSumMemo = (targetSum, numbers, memo = {}) => {
    	if(targetSum in memo) return memo[targetSum]
    
    	// base cases
    	// return different values for different base cases
    	if(targetSum === 0) return []
    	if(targetSum < 0) return null
    
    	// reduce the problem size and solve the sub problem
    	for (let num of numbers) {
    		let remainValue = targetSum - num
    		let temp = howSumMemo(remainValue, numbers, memo)
    		if(temp !== null) {
    			memo[targetSum] = [...temp, num]
    			return memo[targetSum]
    		}
    	}
    
    	memo[targetSum] = null
    	return null
    }
    

    Tabulation

    const howSumTab = (targetSum, numbers) => {
    	// create a table for tabulation
    	// default null assuming the target sum is not possible to get
    	let table = Array(targetSum + 1).fill(null)
    
    	// target sum 0 is possible with empty array
    	table[0] = []
    
    	// we iterate through the table
    	for(let i = 0; i <= targetSum; i++) {
    		// if the value is not null, it means the current target sum (index) is possible
    		if(table[i] !== null) {
    			for(let num of numbers) {
    				// then the num later target sum is also possible
    				table[i + num] = [...table[i], num]
    			}
    		}
    	}
    
    	return table[targetSum]
    }
    

    Reference