Find the least number of coins required that can make any change from 1 to 99 cents

后端 未结 27 2235
生来不讨喜
生来不讨喜 2020-12-07 10:08

Recently I challenged my co-worker to write an algorithm to solve this problem:

Find the least number of coins required that can make any change from

27条回答
  •  佛祖请我去吃肉
    2020-12-07 10:37

    Inspired from this https://www.youtube.com/watch?v=GafjS0FfAC0 following
    1) optimal sub problem 2) Overlapping sub problem principles introduced in the video

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace UnitTests.moneyChange
    {
        public class MoneyChangeCalc
        {
            private static int[] _coinTypes;
    
            private Dictionary _solutions;
    
            public MoneyChangeCalc(int[] coinTypes)
            {
                _coinTypes = coinTypes;
                Reset();
            }
    
            public int Minimun(int amount)
            {
                for (int i = 2; i <= amount; i++)
                {
                    IList candidates = FulfillCandidates(i);
    
                    try
                    {
                        _solutions.Add(i, candidates.Any() ? (candidates.Min() + 1) : 0);
                    }
                    catch (ArgumentException)
                    {
                        Console.WriteLine("key [{0}] = {1} already added", i, _solutions[i]);
                    }
                }
    
                int minimun2;
                _solutions.TryGetValue(amount, out minimun2);
    
                return minimun2;
            }
    
            internal IList FulfillCandidates(int amount)
            {
                IList candidates = new List(3);
                foreach (int coinType in _coinTypes)
                {
                    int sub = amount - coinType;
                    if (sub < 0) continue;
    
                    int candidate;
                    if (_solutions.TryGetValue(sub, out candidate))
                        candidates.Add(candidate);
                }
                return candidates;
            }
    
            private void Reset()
            {
                _solutions = new Dictionary
                    {
                        {0,0}, {_coinTypes[0] ,1}
                    };
            }
        }
    }
    

    Test cases:

    using NUnit.Framework;
    using System.Collections;
    
    namespace UnitTests.moneyChange
    {
        [TestFixture]
        public class MoneyChangeTest
        {
            [TestCaseSource("TestCasesData")]
            public int Test_minimun2(int amount, int[] coinTypes)
            {
                var moneyChangeCalc = new MoneyChangeCalc(coinTypes);
                return moneyChangeCalc.Minimun(amount);
            }
    
            private static IEnumerable TestCasesData
            {
                get
                {
                    yield return new TestCaseData(6, new[] { 1, 3, 4 }).Returns(2);
                    yield return new TestCaseData(3, new[] { 2, 4, 6 }).Returns(0);
                    yield return new TestCaseData(10, new[] { 1, 3, 4 }).Returns(3);
                    yield return new TestCaseData(100, new[] { 1, 5, 10, 20 }).Returns(5);
                }
            }
        }
    }
    

提交回复
热议问题