Skip to content

Commit e62dcfe

Browse files
author
turingfly
committed
Recursion and Dynamic Programming
1 parent b6cd977 commit e62dcfe

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package chapter08RecursionAndDynamicProgramming;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
import chapter05BitManipulation.Conversion;
8+
9+
/**
10+
*
11+
* Problem: Write a method to return all subsets of a set.
12+
*
13+
*/
14+
public class PowerSet {
15+
/**
16+
* Method 1: DFS
17+
*/
18+
public List<List<Integer>> subsets(int[] nums) {
19+
Arrays.sort(nums);
20+
List<List<Integer>> res = new ArrayList<>();
21+
List<Integer> cur = new ArrayList<>();
22+
helper(nums, 0, res, cur);
23+
return res;
24+
}
25+
26+
private void helper(int[] nums, int index, List<List<Integer>> res, List<Integer> cur) {
27+
res.add(new ArrayList<Integer>(cur));
28+
for (int i = index; i < nums.length; i++) {
29+
cur.add(nums[i]);
30+
helper(nums, i + 1, res, cur);
31+
cur.remove(cur.size() - 1);
32+
}
33+
}
34+
35+
/**
36+
* Combinatorics
37+
*/
38+
public List<List<Integer>> subsets2(List<Integer> set) {
39+
List<List<Integer>> res = new ArrayList<>();
40+
int max = 1 << set.size(); // compute 2^N
41+
for (int i = 0; i < max; i++) {
42+
List<Integer> cur = convertIntToSet(set, i);
43+
res.add(cur);
44+
}
45+
return res;
46+
}
47+
48+
private List<Integer> convertIntToSet(List<Integer> set, int x) {
49+
List<Integer> res = new ArrayList<>();
50+
int index = 0;
51+
for (int i = x; i > 0; i >>= 1) {
52+
if ((i & 1) == 1) {
53+
res.add(set.get(index));
54+
}
55+
index++;
56+
}
57+
return res;
58+
}
59+
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package chapter08RecursionAndDynamicProgramming;
2+
3+
/**
4+
*
5+
* Problem: Write a recursive function to multiply two positive integers without
6+
* using the * operator(or / operator). You can use addition, subtraction, and
7+
* bit shifting, but you should minimize the number of those operations.
8+
*
9+
*/
10+
public class RecursiveMultiply {
11+
12+
/**
13+
* Method 1: Duplicate work
14+
*/
15+
public int minProduct1(int a, int b) {
16+
int bigger = a < b ? b : a;
17+
int smaller = a < b ? a : b;
18+
return helper1(smaller, bigger);
19+
}
20+
21+
private int helper1(int smaller, int bigger) {
22+
if (smaller == 0) {
23+
return 0;
24+
} else if (smaller == 1) {
25+
return bigger;
26+
}
27+
// compute half, if uneven, compute other half. if even, double it.
28+
int s = smaller >> 1;
29+
int side1 = helper1(s, bigger);
30+
int side2 = side1;
31+
if (smaller % 2 == 1) {
32+
side2 = helper1(smaller - s, bigger);
33+
}
34+
return side1 + side2;
35+
}
36+
37+
/**
38+
* Method 2: use memorization to cache the results.
39+
*/
40+
public int minProduct2(int a, int b) {
41+
int bigger = a < b ? b : a;
42+
int smaller = a < b ? a : b;
43+
int memo[] = new int[smaller + 1];
44+
return helper2(smaller, bigger, memo);
45+
}
46+
47+
private int helper2(int smaller, int bigger, int[] memo) {
48+
if (smaller == 0) {
49+
return 0;
50+
} else if (smaller == 1) {
51+
return bigger;
52+
} else if (memo[smaller] > 0) {
53+
return memo[smaller];
54+
}
55+
// compute half, if uneven, compute other half. if even, double it.
56+
int s = smaller >> 1;
57+
int side1 = helper1(s, bigger);
58+
int side2 = side1;
59+
if (smaller % 2 == 1) {
60+
side2 = helper2(smaller - s, bigger, memo);
61+
}
62+
memo[smaller] = side1 + side2;
63+
return memo[smaller];
64+
}
65+
66+
/**
67+
* Method 3:minProd(31, 35) = 2 * minProd(15, 35) + 35
68+
*
69+
* The function just recurses straight downwards. It will never repeat the
70+
* same call, so there's no need to cache any information.
71+
*
72+
* Time Complexity: O(logs), where s is the smaller of the tow numbers.
73+
*/
74+
public int minProduct3(int a, int b) {
75+
int bigger = a < b ? b : a;
76+
int smaller = a < b ? a : b;
77+
return helper3(smaller, bigger);
78+
}
79+
80+
private int helper3(int smaller, int bigger) {
81+
if (smaller == 0) {
82+
return 0;
83+
} else if (smaller == 1) {
84+
return bigger;
85+
}
86+
int s = smaller >> 1;
87+
int halfProd = helper3(s, bigger);
88+
if (smaller % 2 == 0) {
89+
return halfProd + halfProd;
90+
} else {
91+
return halfProd + halfProd + bigger;
92+
}
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package chapter08RecursionAndDynamicProgramming;
2+
3+
import java.util.Stack;
4+
5+
/**
6+
*
7+
* Problem:
8+
*
9+
*/
10+
public class TowersOfHanoi {
11+
public static void main(String[] args) {
12+
int n = 3;
13+
Tower[] towers = new Tower[n];
14+
for (int i = 0; i < 3; i++) {
15+
towers[i] = new Tower(i);
16+
}
17+
for (int i = n - 1; i >= 0; i--) {
18+
towers[0].add(i);
19+
}
20+
towers[0].moveDisks(n, towers[2], towers[1]);
21+
}
22+
}
23+
24+
class Tower {
25+
private Stack<Integer> disks;
26+
private int index;
27+
28+
public Tower(int index) {
29+
disks = new Stack<>();
30+
this.index = index;
31+
}
32+
33+
public int getIndex() {
34+
return index;
35+
}
36+
37+
public void add(int d) {
38+
if (!disks.isEmpty() && disks.peek() <= d) {
39+
System.out.println("ERROR placing disk" + d);
40+
} else {
41+
disks.add(d);
42+
}
43+
}
44+
45+
public void moveToTop(Tower t) {
46+
int top = disks.pop();
47+
t.add(top);
48+
}
49+
50+
public void moveDisks(int n, Tower destination, Tower buffer) {
51+
if (n > 0) {
52+
moveDisks(n - 1, buffer, destination);
53+
moveToTop(destination);
54+
buffer.moveDisks(n - 1, destination, this);
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)