Skip to content

Commit 798bd87

Browse files
committed
use dp cache for balanced partition
1 parent d06bfb6 commit 798bd87

File tree

3 files changed

+37
-60
lines changed

3 files changed

+37
-60
lines changed

Advanced.Algorithms.Tests/DynamicProgramming/Sequence/BalancedPartition_Tests.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ public void Partition_Smoke_Test()
2020
{
2121
var input = new int[] { 3, 1, 1, 2, 2, 1, 4 , 2};
2222

23-
var partitionA = BalancedPartition.FindPartition(input);
24-
25-
Assert.AreEqual(8, partitionA
26-
.Select(i => input[i])
27-
.Sum());
28-
29-
var partitionB = input.Where((x, i) => !partitionA.Contains(i)).ToList();
30-
31-
Assert.AreEqual(8,
32-
partitionB.Sum());
23+
Assert.IsTrue(BalancedPartition.CanPartition(input));
3324
}
3425
}
3526
}

Advanced.Algorithms/DynamicProgramming/Sequence/BalancedPartition.cs

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,66 +13,61 @@ public class BalancedPartition
1313
/// </summary>
1414
/// <param name="input"></param>
1515
/// <returns></returns>
16-
public static List<int>
17-
FindPartition(int[] input)
16+
public static bool
17+
CanPartition(int[] input)
1818
{
1919
var sum = FindSum(input);
2020

2121
if (sum % 2 == 1)
2222
{
2323
//cannot partition
24-
return new List<int>();
24+
return false;
2525
}
2626

27-
var result = new List<int>();
28-
29-
var canPartition = Partition(sum / 2, input, 0, 0, result);
30-
31-
return result;
27+
return CanPartition(input, input.Length - 1, sum / 2, new Dictionary<string, bool>());
3228

3329
}
3430

35-
/// <summary>
36-
/// Dynamic recursion
37-
/// </summary>
38-
/// <param name="sum"></param>
39-
/// <param name="input"></param>
40-
/// <param name="index"></param>
41-
/// <param name="progress"></param>
42-
/// <param name="pickedIndices"></param>
43-
/// <returns></returns>
44-
private static bool Partition(int sum,
45-
int[] input, int index,
46-
int progress,
47-
List<int> pickedIndices)
31+
private static bool CanPartition(int[] input, int i, int sum,
32+
Dictionary<string, bool> cache)
4833
{
49-
//found result
50-
if (sum == 0)
34+
if (i < 0)
5135
{
52-
return true;
36+
return false;
5337
}
5438

55-
//cannot pick this value
56-
//which is greater than current sum
57-
if (input[index] > sum)
39+
//found a partition
40+
if (input[i] == sum)
5841
{
59-
return Partition(sum, input, index + 1, progress, pickedIndices);
42+
return true;
6043
}
6144

62-
//pick current element
63-
var canPartition = Partition(sum - input[index], input,
64-
index + 1, progress + 1, pickedIndices);
45+
var cacheKey = $"{i}-{sum}";
46+
47+
if (cache.ContainsKey(cacheKey))
48+
{
49+
return cache[cacheKey];
50+
}
6551

66-
if (canPartition)
52+
bool result;
53+
//cannot pick anyway
54+
if (input[i] > sum)
6755
{
68-
pickedIndices.Add(index);
69-
return canPartition;
56+
result = CanPartition(input, i - 1, sum, cache);
57+
cache.Add(cacheKey, result);
58+
return result;
7059
}
7160

72-
//skip current element
73-
canPartition = Partition(sum, input, index + 1, progress, pickedIndices);
61+
//skip or pick
62+
result = CanPartition(input, i - 1, sum, cache)
63+
|| CanPartition(input, i - 1, sum - input[i], cache);
7464

75-
return canPartition;
65+
if (!cache.ContainsKey(cacheKey))
66+
{
67+
cache.Add(cacheKey, result);
68+
}
69+
70+
return result;
7671
}
7772

7873
private static int FindSum(int[] input)

Advanced.Algorithms/DynamicProgramming/TowerOfHanoi.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ public static int Tower(int numOfDisks)
2424
/// <param name="moveCount"></param>
2525
private static int Tower(int n, string source, string aux, string dest, Dictionary<int, int> cache)
2626
{
27-
Debug.WriteLine("Moving disc {0} from pole {1} to {2}", n, source, dest);
28-
2927
if (n == 1)
3028
{
3129
return 1;
@@ -36,20 +34,13 @@ private static int Tower(int n, string source, string aux, string dest, Dictiona
3634
return cache[n];
3735
}
3836

39-
////assume without last disc on top we would be moving a disc from source to dest
40-
//Tower(n - 1, source, aux, dest, ref moveCount);
41-
42-
////The last disc we just moved above to destination was in source
43-
////that disc was definitely moved from aux to source (if it was in destination we would be not here)
44-
//Tower(n - 1, aux, dest, source, ref moveCount);
45-
46-
//or alternatively
4737
//assume without last disc on top we would be moving a disc from aux to dest
4838
var result = Tower(n - 1, aux, source, dest, cache)
39+
//The last disc we just moved above to destination was in aux
40+
//that disc was definitely moved from source to aux (if it was in destination we would be done by now)
41+
//+1 for current move
42+
+ Tower(n - 1, source, dest, aux, cache) + 1;
4943

50-
//The last disc we just moved above to destination was in aux
51-
//that disc was definitely moved from source to aux (if it was in destination we would be done by now)
52-
+ Tower(n - 1, source, dest, aux, cache) + 1;
5344

5445
cache.Add(n, result);
5546

0 commit comments

Comments
 (0)