diff --git a/lib/possible_bipartition.rb b/lib/possible_bipartition.rb index 69507f1..a145aa0 100644 --- a/lib/possible_bipartition.rb +++ b/lib/possible_bipartition.rb @@ -1,4 +1,48 @@ +# I looked at the leetcode solution in Python +# (https://leetcode.com/problems/possible-bipartition/solution/) +# to get an idea of how to turn the list of dislikes into a graph, +# but chose to implement a breadth-first solution instead def possible_bipartition(dislikes) - raise NotImplementedError, "possible_bipartition isn't implemented yet" + return true if dislikes.empty? + graph = build_graph(dislikes) + # start with an arbitrary node of the graph, + # assuming all nodes have at least one edge + grouped = {graph.keys[0] => true} + queue = [graph.keys[0]] + # using a bfs approach, set all neighbor nodes to the opposite label + # and add them to the queue if they haven't been visited + # return false if a neighbor has the same label as the current node + while !queue.empty? + node = queue.shift() + graph[node].each do |neighbor| + if grouped[neighbor] == nil + grouped[neighbor] = !grouped[node] + queue.push(neighbor) + elsif grouped[neighbor] == grouped[node] + return false + end + end + if queue.empty? + graph.keys.each do |key| + if grouped[key].nil? + queue.push(key) + break + end + end + end + end + return true end + + +def build_graph(dislikes) + nodes = Hash.new {|h,k| h[k] = [] } #had to look up how to do this on StackOverflow + dislikes.each do |dislike| + dislike.each do |node| + nodes[node] += dislike - [node] + end + end + return nodes +end + diff --git a/test/possible_bipartition_test.rb b/test/possible_bipartition_test.rb index d40fe14..26a2c57 100644 --- a/test/possible_bipartition_test.rb +++ b/test/possible_bipartition_test.rb @@ -17,7 +17,7 @@ expect(answer).must_equal true end - it "will work for example 2" do + it "will work for example 2" do # Arrange dislikes = [ [], [2, 3], @@ -49,7 +49,7 @@ expect(answer).must_equal false end - it "will return true for a graph which can be bipartitioned" do + it "will return true for a graph which can be bipartitioned" do # Arrange dislikes = [ [3, 6], [2, 5], @@ -68,7 +68,7 @@ end - it "will return false for a graph which cannot be bipartitioned" do + it "will return false for a graph which cannot be bipartitioned" do # Arrange dislikes = [ [3, 6], [2, 5], @@ -89,4 +89,39 @@ it "will work for an empty graph" do expect(possible_bipartition([])).must_equal true end +end + +describe "edge cases" do + it "will work for a graph where all nodes are not interconnected" do + # Arrange + dislikes = [ + [1,2], + [3,4], + [4,5], + [3,5]] + + # Act + answer = possible_bipartition(dislikes) + + # Assert + expect(answer).must_equal false + + end + + it "will work for a graph where all nodes don't have dislikes" do + # Arrange + dislikes = [ + [1,2], + [4,5], + [5,6], + [4,6]] + + # Act + answer = possible_bipartition(dislikes) + + # Assert + expect(answer).must_equal false + + end + end \ No newline at end of file