From 13aec345eaca265cc5ea218754faefc62fe557a6 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Thu, 1 Apr 2021 09:54:34 -0700 Subject: [PATCH 1/5] add generate_parenthesis backtracking approach --- backtracking/generate_paranthesis.rb | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 backtracking/generate_paranthesis.rb diff --git a/backtracking/generate_paranthesis.rb b/backtracking/generate_paranthesis.rb new file mode 100644 index 0000000..5881aea --- /dev/null +++ b/backtracking/generate_paranthesis.rb @@ -0,0 +1,47 @@ +# Given n pairs of parentheses, write a function to generate all combinations +# of well-formed parentheses. +# +# Example 1: +# +# Input: n = 3 +# Output: ["((()))","(()())","(())()","()(())","()()()"] +# Example 2: +# +# Input: n = 1 +# Output: ["()"] +# +# +# Constraints: +# +# 1 <= n <= 8 + +# @param {Integer} n +# @return {String[]} +def generate_parenthesis(n) + parenthesis = [] + backtrack(parenthesis, "", 0, 0, n) + parenthesis +end + +def backtrack(parenthesis, curr, open, close, max) + if curr.length == max * 2 + parenthesis.push(curr) + return + end + + if open < max + backtrack(parenthesis, curr + "(", open + 1, close, max) + end + + if close < open + backtrack(parenthesis, curr + ")", open, close + 1, max) + end +end + +n = 3 +print(generate_parenthesis(n)) +# Output: ["((()))","(()())","(())()","()(())","()()()"] + +n = 1 +print(generate_parenthesis(n)) +# Output: ["()"] From 1350b46474aa437169639166e041ebdfdaa469af Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 1 Apr 2021 16:54:50 +0000 Subject: [PATCH 2/5] updating DIRECTORY.md --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 42b9add..7c86a15 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,4 +1,7 @@ +## Backtracking + * [Generate Paranthesis](https://github.com/TheAlgorithms/Ruby/blob/master/backtracking/generate_paranthesis.rb) + ## Bit Manipulation * [Power Of Two](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/power_of_two.rb) From 1d974b2ea18e646fe277ada716902d42ed95c659 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Thu, 1 Apr 2021 09:58:04 -0700 Subject: [PATCH 3/5] Add approach description --- backtracking/generate_paranthesis.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backtracking/generate_paranthesis.rb b/backtracking/generate_paranthesis.rb index 5881aea..587a25c 100644 --- a/backtracking/generate_paranthesis.rb +++ b/backtracking/generate_paranthesis.rb @@ -15,6 +15,16 @@ # # 1 <= n <= 8 +# Approach: +# +# Let's only add '(' or ')' when we know it will remain a valid sequence. +# We can do this by keeping track of the number of opening and closing brackets +# we have placed so far. +# +# We can start an opening bracket if we still have one (of n) left to place. +# And we could start a closing bracket if it'd not exceed the number of opening +# brackets. + # @param {Integer} n # @return {String[]} def generate_parenthesis(n) From 7eea20ed6e0369db5d5ff8d2f99aa431ac78a224 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Thu, 1 Apr 2021 10:06:40 -0700 Subject: [PATCH 4/5] Add complexity analysis and detailed example --- backtracking/generate_paranthesis.rb | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/backtracking/generate_paranthesis.rb b/backtracking/generate_paranthesis.rb index 587a25c..0ea684e 100644 --- a/backtracking/generate_paranthesis.rb +++ b/backtracking/generate_paranthesis.rb @@ -25,6 +25,14 @@ # And we could start a closing bracket if it'd not exceed the number of opening # brackets. +# Complexity Analysis +# +# Time Complexity: O(4^n/sqrt(n). Each valid sequence has at most n steps during the backtracking procedure. +# Space Complexity: O(4^n/sqrt(n), as described above, and using O(n) space to store the sequence. + +# Refer to the attached diagram for recursion, +# The numbers next to each node are the counts of left and right parantheses + # @param {Integer} n # @return {String[]} def generate_parenthesis(n) @@ -52,6 +60,47 @@ n = 3 print(generate_parenthesis(n)) # Output: ["((()))","(()())","(())()","()(())","()()()"] +# *** Example: n = 3 *** Space after each DFS instance +# backtrack called with 0 0 [] +# backtrack called with ( 1 0 [] +# backtrack called with (( 2 0 [] +# backtrack called with ((( 3 0 [] +# backtrack called with ((() 3 1 [] +# backtrack called with ((()) 3 2 [] +# backtrack called with ((())) 3 3 [] +# backtrack return with ((()) 3 2 ["((()))"] +# backtrack return with ((() 3 1 ["((()))"] +# backtrack return with ((( 3 0 ["((()))"] +# backtrack called with (() 2 1 ["((()))"] +# backtrack called with (()( 3 1 ["((()))"] +# backtrack called with (()() 3 2 ["((()))"] +# backtrack called with (()()) 3 3 ["((()))"] +# backtrack return with (()() 3 2 ["((()))", "(()())"] +# backtrack return with (()( 3 1 ["((()))", "(()())"] +# backtrack called with (()) 2 2 ["((()))", "(()())"] +# backtrack called with (())( 3 2 ["((()))", "(()())"] +# backtrack called with (())() 3 3 ["((()))", "(()())"] +# backtrack return with (())( 3 2 ["((()))", "(()())", "(())()"] +# backtrack return with (()) 2 2 ["((()))", "(()())", "(())()"] +# backtrack return with (() 2 1 ["((()))", "(()())", "(())()"] +# backtrack return with (( 2 0 ["((()))", "(()())", "(())()"] +# backtrack called with () 1 1 ["((()))", "(()())", "(())()"] +# backtrack called with ()( 2 1 ["((()))", "(()())", "(())()"] +# backtrack called with ()(( 3 1 ["((()))", "(()())", "(())()"] +# backtrack called with ()(() 3 2 ["((()))", "(()())", "(())()"] +# backtrack called with ()(()) 3 3 ["((()))", "(()())", "(())()"] +# backtrack return with ()(() 3 2 ["((()))", "(()())", "(())()", "()(())"] +# backtrack return with ()(( 3 1 ["((()))", "(()())", "(())()", "()(())"] +# backtrack called with ()() 2 2 ["((()))", "(()())", "(())()", "()(())"] +# backtrack called with ()()( 3 2 ["((()))", "(()())", "(())()", "()(())"] +# backtrack called with ()()() 3 3 ["((()))", "(()())", "(())()", "()(())"] +# backtrack return with ()()( 3 2 ["((()))", "(()())", "(())()", "()(())", "()()()"] +# backtrack return with ()() 2 2 ["((()))", "(()())", "(())()", "()(())", "()()()"] +# backtrack return with ()( 2 1 ["((()))", "(()())", "(())()", "()(())", "()()()"] +# backtrack return with () 1 1 ["((()))", "(()())", "(())()", "()(())", "()()()"] +# backtrack return with ( 1 0 ["((()))", "(()())", "(())()", "()(())", "()()()"] +# backtrack return with 0 0 ["((()))", "(()())", "(())()", "()(())", "()()()"] + n = 1 print(generate_parenthesis(n)) # Output: ["()"] From fc0c664f6bd123fd2e6f5dba7a06c05497240866 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Thu, 1 Apr 2021 10:45:41 -0700 Subject: [PATCH 5/5] close ) --- backtracking/generate_paranthesis.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backtracking/generate_paranthesis.rb b/backtracking/generate_paranthesis.rb index 0ea684e..5c0e3fa 100644 --- a/backtracking/generate_paranthesis.rb +++ b/backtracking/generate_paranthesis.rb @@ -27,8 +27,8 @@ # Complexity Analysis # -# Time Complexity: O(4^n/sqrt(n). Each valid sequence has at most n steps during the backtracking procedure. -# Space Complexity: O(4^n/sqrt(n), as described above, and using O(n) space to store the sequence. +# Time Complexity: O(4^n/sqrt(n)). Each valid sequence has at most n steps during the backtracking procedure. +# Space Complexity: O(4^n/sqrt(n)), as described above, and using O(n) space to store the sequence. # Refer to the attached diagram for recursion, # The numbers next to each node are the counts of left and right parantheses