Browse Source

Adding two recursive methods to new recursion folder.

master
Charles Reid 8 years ago
parent
commit
e0ada373bd
  1. 72
      recursion/threesum/SubsetSum.java
  2. 73
      recursion/threesum/TripleSum.java

72
recursion/threesum/SubsetSum.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
import java.util.*;
import java.io.*;
/** Find number of subsets of numbers that sum to 0.
*
* Uses recursive backtracking, and two stacks of integers.
*
* */
public class SubsetSum {
private static int nsolutions = 0;
public static void subsetSums(List<Integer> list) {
explore(list);
}
public static int sum(List<Integer> list) {
int sum = 0;
for(int i=0; i<list.size(); i++) {
sum += list.get(i);
}
return sum;
}
public static void explore(List<Integer> superset) {
List<Integer> brandnew = new ArrayList<Integer>();
System.out.println(explore_(superset, brandnew));
}
private static int explore_(List<Integer> unchosen, List<Integer> chosen) {
if(unchosen.isEmpty()) {
// base case
//
// We may find a combination at any point, so we can never "end early".
// We can only keep going until unchosen is empty.
return nsolutions;
} else {
// Check if we have found a sum, in which case, yay!
if( sum(chosen)==0 ) {
//System.out.println(chosen);
nsolutions++;
}
// recursive case
for(int j = 0; j < unchosen.size(); j++ ) {
// Make a choice
Integer element = unchosen.get(j);
unchosen.remove(j);
chosen.add(element);
// Explore consequences
explore_(unchosen, chosen);
// Unmake the choice
chosen.remove(chosen.size()-1);
unchosen.add(j,element);
} // move on to next choice
}
return nsolutions;
}
public static void main(String[] args) {
Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
List<Integer> list = new ArrayList<Integer>();
while(in.hasNextInt()){
list.add(in.nextInt());
}
subsetSums(list);
}
}

73
recursion/threesum/TripleSum.java

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
// Code Jam starting strategy:
import java.util.*;
import java.io.*;
public class TripleSum {
/** Print all triples ijk such that a[i]+a[j]+a[k] = 0.
* Keep it simple:
* straightforward approach, simple variable names,
* easy algorithm analysis, printf - only the basics.
*/
public static void printAll(int[] arr) {
int n = arr.length;
for(int i=0; i<n; i++ ) {
for(int j=i+1; j<n; j++) {
for(int k=j+1; k < n; k++) {
if( arr[i] + arr[j] + arr[k] == 0 ) {
System.out.printf("%4d %4d %4d \n",arr[i],arr[j],arr[k]);
}
}
}
}
}
/** count all triples ijk such that a[i]+a[j]+a[k] = 0.
* If the purpose is to time an algorithm,
* don't include an if switch that will have to be checked a bazillion times.
* */
public static int countAll(int[] arr) {
int n = arr.length;
int count = 0;
for(int i=0; i<n; i++ ) {
for(int j=i+1; j<n; j++) {
for(int k=j+1; k < n; k++) {
if( arr[i] + arr[j] + arr[k] == 0 ) {
count++;
}
}
}
}
return count;
}
public static void main(String[] args) {
// Code Jam starting strategy:
Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
// Scanner is easy to use. If not... super awkward...
// Load numbers into ArrayList
ArrayList<Integer> alist = new ArrayList<Integer>();
while(in.hasNextInt()) {
alist.add(in.nextInt());
}
// turn ArrayList into int[]
int[] a = new int[alist.size()];
for(int i=0; i<alist.size(); i++) {
a[i] = alist.get(i);
}
// Time
long start = System.currentTimeMillis();
int count = countAll(a);
long now = System.currentTimeMillis();
double elapsed = (now - start) / 1000.0;
System.out.printf("elapsed time = %.4f\n",elapsed);
System.out.println(count);
}
}
Loading…
Cancel
Save