This problem is found here: http://learningandtheadolescentmind.org/resources_02_bucket.html
I called it three "Ice Bucket Challenge" for fun. ;) Here is the problem description.
There are an 8-liter bucket filled with ice water and empty 3-liter and
5-liter buckets. You solve the puzzle by using the three buckets to
divide the 8 liters of water into two equal parts of 4 liters. Try to solve the
puzzle in the fewest number of moves.
Although to find a fewest number of moves is not easy, but I can design depth first search to find the necessary moves to distribute the waters.
Here is the code
The idea here is to for each possible case, we find the all possible cases which can be derived from it. For example, from 8, 0, 0, it could be 5, 0, 3 or 3, 5, 0. And we use a list keep track of the cases we already visited. Think of all possible cases as a graph, we essentially do a depth first search until we find the case contains 4.
A potential solution to find the fewest moves is to use the breath first search. We can use a Queue to contain the list of cases we already visited, then generate the queue of next level based on that, also keep track of the parent case for each case in the queue until we find the case.
Showing posts with label DFS. Show all posts
Showing posts with label DFS. Show all posts
Friday, February 12, 2016
Monday, October 26, 2015
find all palidrome partitions for a string
This problem is from LeetCode:
http://www.programcreek.com/2013/03/leetcode-palindrome-partitioning-java/
Given a string s, partition s such that every substring of the partition is a palindrome.
we can think all possible palindromic substrings form a graph.
each palindromic substring is the node
two nodes connect each other when one's starting index is equal to
the other ending index. There are multiple roots in this graph but only one leaf.
roots are the palidrome substrings starting at index 0
leaf are the node with starting index equals to string's length
a path from root to leaf is one palindrome partition
public static void findAllPali(String s){
dfs(s, 0, new ArrayList<String>());
}
public static void dfs(String s, int start, List<String> current){
//reach leaf level, then we find the palidrome partition
if(start==s.length()){
System.out.println(current);
return;
}
for(int j=start+1;j<=s.length();j++){
//depth first search
//find one node
if(isPali(s, start, j-1)){
/*
* before we go down this branch
* we make copy of the path
* then pass it down
*/
List<String> copy = new ArrayList<String>(current);
copy.add(s.substring(start, j));
dfs(s, j, copy);
}
}
}
public static boolean isPali(String s, int i, int j){
while(i<j){
if(s.charAt(i)!=s.charAt(j))
return false;
i++;j--;
}
return true;
}
http://www.programcreek.com/2013/03/leetcode-palindrome-partitioning-java/
Given a string s, partition s such that every substring of the partition is a palindrome.
we can think all possible palindromic substrings form a graph.
each palindromic substring is the node
two nodes connect each other when one's starting index is equal to
the other ending index. There are multiple roots in this graph but only one leaf.
roots are the palidrome substrings starting at index 0
leaf are the node with starting index equals to string's length
a path from root to leaf is one palindrome partition
public static void findAllPali(String s){
dfs(s, 0, new ArrayList<String>());
}
public static void dfs(String s, int start, List<String> current){
//reach leaf level, then we find the palidrome partition
if(start==s.length()){
System.out.println(current);
return;
}
for(int j=start+1;j<=s.length();j++){
//depth first search
//find one node
if(isPali(s, start, j-1)){
/*
* before we go down this branch
* we make copy of the path
* then pass it down
*/
List<String> copy = new ArrayList<String>(current);
copy.add(s.substring(start, j));
dfs(s, j, copy);
}
}
}
public static boolean isPali(String s, int i, int j){
while(i<j){
if(s.charAt(i)!=s.charAt(j))
return false;
i++;j--;
}
return true;
}
Friday, January 9, 2015
Topological sort of airports
A friend of mine presents the following problem to, given a list of airports, LAX, PHL, LGA, JFK, EWK and list of routes between them: LAX->PHL, LGA->EWK, JFK->LAX, construct the whole path to connect those airports. The route can start with any airports and end at any airports.
The key to topological sort is to do DFS, then add the visited node at the end, in that way the the nodes are sorted.
public class Airport {
public Airport(String from) {
this.name = from;
this.destinations = new ArrayList<Airport>();
}
String name;
List<Airport> destinations;
}
public class Edge{
String from;
String to;
}
public Stack<Airport> sortAirports(List<Edge> edges){
Map<String, Airport> graph = new HashMap<String, Airport>();
buildGraph(edges, graph);
Set<String> visited = new HashSet<String>();
Stack<Airport> s = new Stack<Airport>();
for(Airport a : graph.values()){
sort(a, s, visited);
}
return s;
}
public void sort(Airport a, Stack<Airport> s, Set<String> visited){
if(visited.contains(a.name))
return;
visited.add(a.name);
for(Airport d : a.destinations){
sort(d, s, visited);
}
s.add(a); <== add the earlier visited airport at last
}
Wednesday, January 7, 2015
Find diameter for any tree
The diameter of a tree is the maximum length of path between any vertex in a tree. The simple solution is to start from any vertex, do a DFS, find a farthest vertex from it, then from that farthest vertex, do second DFS, find the farthest vertex from it.
//here is the graph node with adjacentList representation.
//for illustration purpose, the key of each vertex is character
//here is the graph node with adjacentList representation.
//for illustration purpose, the key of each vertex is character
public static class CNode {
char c;
Set<CNode> outgoing = new HashSet<CNode>();
CNode(char i){this.c=i;}
public int hashCode() {}
public boolean equals(Object o){}
}
public static int diameterOfTree(CNode[] vertices){
int[] max = new int[1];
CNode[] mNode = new CNode[1];
Set<CNode> visited = new HashSet<CNode>();
//start with any vertex in the tree
dfs(vertices[0], 0, visited, max, mNode);
CNode[] maxNode = new CNode[1];
max[0] = 0;
visited = new HashSet<CNode>();
dfs(mNode[0], 0, visited, max, maxNode);
return max[0];
}
public static void dfs(CNode start, int distance, Set<CNode> visited, int[] max, CNode[] maxNode){
visited.add(start);
max[0] = Math.max(max[0], distance);
if(max[0]==distance)
maxNode[0] = start;
for(CNode n : start.outgoing){
if(!visited.contains(n)){
dfs(n, distance+1, visited, max, maxNode);
}
}
}
Subscribe to:
Posts (Atom)