Generate balanced parentheses in java - java

The question is:
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
I used to solve this problem using string as following codes:
public class Solution {
public List<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
//StringBuilder s = new StringBuilder();
generate(n, 0, 0, "", result);
return result;
}
public void generate(int n, int left, int right, String s, ArrayList<String> result){
//left is num of '(' and right is num of ')'
if(left < right){
return;
}
if(left == n && right == n){
result.add(s);
return;
}
if(left == n){
//add ')' only.
generate(n, left, right + 1, s + ")", result);
return;
}
generate(n, left + 1, right, s + "(", result);
generate(n, left, right + 1, s + ")", result);
}
}
Now I want to solve this problem using StringBuilder, the code is like this:
import java.util.ArrayList;
public class generateParentheses {
public static ArrayList<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
generate(n, 0, 0, result, sb);
return result;
}
public static void generate(int n, int left, int right, ArrayList<String> result,
StringBuilder sb) {
if (left < right) {
return;
}
if (left == n && right == n) {
result.add(sb.toString());
sb = new StringBuilder();
return;
}
if (left == n) {
generate(n, left, right + 1, result, sb.append(')'));
return;
}
generate(n, left + 1, right, result, sb.append('('));
//sb.delete(sb.length(), sb.length() + 1);
generate(n, left, right + 1, result, sb.append(')'));
//sb.delete(sb.length(), sb.length() + 1);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(generateParenthesis(4));
}
}
The result is not what I want:
(((()))), (((()))))())), (((()))))())))()), (((()))))())))()))(), (((()))))())))()))()))(())), (((()))))())))()))()))(())))()).........
Is there anyone tell me what is the problem? Thank you very much.

You ware close. Your mistakes ware:
trying to reset sb instead of removing only its last character
way you want to reset sb:
by using sb = new StringBuilder(); you are reassigning sb which is local variable of current method, not variable of method which invoked it (Java is not pass-by-reference but pass-by-value).
your almost correct attempt ware commented sb.delete(sb.length(), sb.length() + 1); but here you are actually trying to remove characters starting from position sb.length(), but just like arrays indexes of character in StringBuilder are from 0 till sb.length() - 1 so is trying to remove one character after last character which effectively can't remove anything.
What you needed here is
sb.delete(sb.length() - 1, sb.length());
or more readable
sb.deleteCharAt(sb.length() - 1);
but probably best approach in terms of performance setLength (described at bottom of answer)
sb.setLength(sb.length() - 1);
your logic of when to remove characters from StringBuilder is also flawed
you are doing it only in one place which ends (backtracks) recursive calls: after finding correct results. But what about other cases like if (left < right) or most importantly, if method will end normally like
generate(3, 1, 1, ')');
generate(3, 1, 2, ')');//here we stop and backtrack
Here generate(3, 1, 2, ')'); ends and removes last character from sb, but shouldn't previous method generate(3, 1, 1, ')') also remove its own ) added to StringBuilder?
In other words you shouldn't remove last character only at end of successful condition in recursive call, but after each recursive call, to make sure that method will also remove character it adds.
So change your code to something like
public static void generate(int n, int left, int right, ArrayList<String> result,
StringBuilder sb) {
if (left < right) {
return;
}
if (left == n && right == n) {
result.add(sb.toString());
return;
}
if (left == n) {
generate(n, left, right + 1, result, sb.append(')'));
sb.deleteCharAt(sb.length() - 1);// <--
return;
}
generate(n, left + 1, right, result, sb.append('('));
sb.deleteCharAt(sb.length() - 1);// <--
generate(n, left, right + 1, result, sb.append(')'));
sb.deleteCharAt(sb.length() - 1);// <--
}
or try writing something probably more readable like
public static void generate(int maxLength, int left, int right,
ArrayList<String> result, StringBuilder sb) {
if (left + right == maxLength) {
if (left == right)
result.add(sb.toString());
} else if (left >= right) {
generate(maxLength, left + 1, right, result, sb.append('('));
sb.deleteCharAt(sb.length() - 1);
generate(maxLength, left, right + 1, result, sb.append(')'));
sb.deleteCharAt(sb.length() - 1);
}
}
but while invoking you would need to set maxLength as 2*n since it is the max length StringBuilder should contain, so you would also have to change generateParenthesis(int n) to:
public static ArrayList<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder(2 * n);
generate(2 * n, 0, 0, result, sb);
// ^^^^^
return result;
}
Farther improvement:
If you are aiming for performance then you probably don't want to use delete or deleteCharAt because each time it creates new array and fills it with copy of values from without ones you don't want.
Instead you can use setLength method. If you will pass value which is smaller than number of currently stored characters it will set count to value passed in this method, which will effectively make characters after them irrelevant. In other words this characters will be no longer used in for instance toString() even if they will be still in StringBuilder buffer array.
Example:
StringBuilder sb = new StringBuilder("abc"); // 1
sb.setLength(2); // 2
System.out.println(sb); // 3
sb.append('d'); // 4
System.out.println(sb); // 5
In line 1 StringBuilder will allocate array for at least 3 characters (by default it uses str.length() + 16 to determine size of buffered array of characters it will store for now) and will place there characters from passed String, so it will contain
['a', 'b', 'c', '\0', '\0', ... , '\0']
^^^ - it will put next character here
Index of position where next character should be placed is stored in count field and for now it is equal to 3.
In line 2 value of count will be set to 2, but our array will not be changed so it will still look like
['a', 'b', 'c', '\0', '\0', ... , '\0']
^^^ - it will put next character here
In line 3 new String will be created and printed, but it will be filled only with characters placed before index stored in count, which means that it will contain only a and b (array will still be unchanged).
In line 4 you will add new character to buffer and it will be placed after "important" characters. Since number of important characters is stored in count field (and they are placed at beginning of array), next irrelevant character must be at position pointed by count, which means d will be placed at position with index 2 which means now array will look like
['a', 'b', 'd', '\0', '\0', ... , '\0']
^^^ - it will put next character here
and value of count will be incremented (we added only one character so count will now become 3).
In line 5 we will create and print string containing first 3 characters from array used by StringBuilder so we will see abd.

After carefully debuting this program, I found out the problem. The correct code is listed as follows:
import java.util.ArrayList;
public class generateParentheses {
public static ArrayList<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
generate(n, 0, 0, result, sb);
return result;
}
public static void generate(int n, int left, int right, ArrayList<String> result,
StringBuilder sb) {
if (left < right) {
return;
}
if (left == n && right == n) {
result.add(sb.toString());
//sb.delete(0,sb.length());
return;
}
if (left == n) {
generate(n, left, right + 1, result, sb.append(')'));
//delete current ')'.
sb.delete(sb.length() - 1, sb.length());
return;
}
generate(n, left + 1, right, result, sb.append('('));
//delete current '(' after you finish using it for next recursion.
sb.delete(sb.length() - 1, sb.length());
generate(n, left, right + 1, result, sb.append(')'));
//same as above here.
sb.delete(sb.length() - 1, sb.length());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(generateParenthesis(4));
}
}
And the result is:
(((()))), ((()())), ((())()), ((()))(), (()(())), (()()()), (()())(), (())(()), (())()(), ()((())), ()(()()), ()(())(), ()()(()), ()()()()

The combination of a parameter, assigment and return:
..., StringBuilder sb,...
//...
sb = new StringBuilder();
return sb;
does not make sense, because the parameter is passed in by value, i.e., sb is a local variable the change of which has no effect in the calling environment.
If you want to clear the StringBuilder, there is method sb.delete( start, end ) that will truly affect the object referenced via sb.

Another much simpler way of doing this.
Here, i am trying for a recursive solution where the recursive function adds balanced parentheses in 3 ways: "()"+result and result+"()" and "("+result+")" for each item in HashSet returned by the function it calls then put them in a HashSet to remove duplicates.
import java.util.HashSet;
import java.util.Set;
public class BalancedParanthesis {
public static void main(String args[]){
int noOfBrackets = 3;
HashSet<String> hs=new HashSet(generate(noOfBrackets));
System.out.println(hs);
}
public static HashSet<String> generate(int in)
{
HashSet<String> hs= new HashSet<String>();
if(in ==1)
{
hs.add("()");
return hs;
}
else{
Set<String> ab=generate(in-1);
for(String each:ab)
{
hs.add("("+each+")");
hs.add("()"+each);
hs.add(each+"()");
}
return hs;
}
}
}

Your code is inefficient. Here is a better approach. We make an effective brute force over the 2^N possible bracket permutations with heavy pruning(we quit the recursion immediately if there is no possible valid solution for the current parameters).
Here's the code in C++:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
string result;
vector<string> solutions;
int N = 10;
void generateBrackets(int pos, int balance)
{
if(balance > N-pos) return;
if(pos == N)
{
//we have a valid solution
//generate substring from 0 to N-1
//and push it to the vector
string currentSolution;
for(int i = 0; i < N; ++i)
{
currentSolution.push_back(result[i]);
}
solutions.push_back(currentSolution);
return;
}
result[pos] = '(';
generateBrackets(pos+1, balance+1);
if(balance > 0)
{
result[pos] = ')';
generateBrackets(pos+1, balance-1);
}
}
int main()
{
result.assign(N, 'a');
generateBrackets(0, 0);
cout<<"Printing solutions:\n";
for(int i = 0; i < solutions.size(); ++i)
{
cout<<solutions[i]<<endl;
}
return 0;
}
Some clarifications: pos marks the current position in the bracket solution we are generating. If we reach position N (that means the solution is valid) we have a valid solution in the string result variable and we simple push it in the vector with the valid solutions. Now for what we use balance you may ask. We make the observation that in order a bracket permutation to be valid, at any time at any given position the count of the '(' from the start must be greater than the count of the ')'s and with balance we measure their difference, so me put a ')' at a given position only if the balance > 0.

Related

Filter odd numbers recursively

How would you solve the following task:
Write a recursive method which gets passed an array, filters all odd numbers and store them into an array. The returned array has to be sorted by each elements order.
You are not allowed to use any provided methods by java classes like Arrays.sort, Lists, etc. Furthermore loops are disallowed and generic well known sort algorithm applied to the result as well.
The part of filtering is easy, but I don't know how to put each element at its right place. At the moment my method only returns an unsorted array with all odd numbers.
public static int[] filterOdd(int[] m){
return filterOdd(m, 0, 0);
}
private static int[] filterOdd(int[] m, int idx, int idxToPlace){
if(idx <= m.length -1){
if(m[idx] % 2 == 0){
return filterOdd(m, idx + 1, idxToPlace);
}else{
int[] buffer = filterOdd(m, idx + 1, idxToPlace + 1);
buffer[idxToPlace] = m[idx];
return buffer;
}
}else{
return new int[numberOfOddIntegers(m)];
}
}
Is there any way to insert the odd number at its right place recursively?
At the place where you do buffer[idxToPlace] = m[idx]; you have to call another method that will return the sorted array with the current processing number added to it.
That new method can be recursive too: you know at that moment that the array you have in your hands is ordered. You just recursively traverse (for example from the end to the begin) and from the moment your element fits in (e.g. is smaller than the previous element) you can insert it and return the sorted array. If there is only 1 element (base case) you can just return it.
That way, at the end of your algorithm, the list will be sorted.
I'm not allowed to use System.arraycopy
This means that you need to figure out how many odd numbers you are going to have, in order to size your result properly:
public static int[] filterOdd(int[] m){
int[] res = new int[countOdd(m, 0)];
filterOdd(m, 0, 0, res);
return res;
}
private static int countOdd(int[] m, int i) {
if (i == m.length) {
return 0;
}
int isOdd = m[i] % 2 != 0 ? 1 : 0;
return isOdd + countOdd(m, i+1);
}
private static void filterOdd(int[] m, int src, int dest, int[] res){
if(src == m.length) {
return;
}
if (m[src] % 2 != 0) {
res[dest++] = m[src];
}
filterOdd(m, src+1, dest, res);
}

Generating all permutations of a certain length

Suppose we have an alphabet "abcdefghiklimnop". How can I recursively generate permutations with repetition of this alphabet in groups of FIVE in an efficient way?
I have been struggling with this a few days now. Any feedback would be helpful.
Essentially this is the same as: Generating all permutations of a given string
However, I just want the permutations in lengths of FIVE of the entire string. And I have not been able to figure this out.
SO for all substrings of length 5 of "abcdefghiklimnop", find the permutations of the substring. For example, if the substring was abcdef, I would want all of the permutations of that, or if the substring was defli, I would want all of the permutations of that substring. The code below gives me all permutations of a string but I would like to use to find all permutations of all substrings of size 5 of a string.
public static void permutation(String str) {
permutation("", str);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0) System.out.println(prefix);
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
In order to pick five characters from a string recursively, follow a simple algorithm:
Your method should get a portion filled in so far, and the first position in the five-character permutation that needs a character
If the first position that needs a character is above five, you are done; print the combination that you have so far, and return
Otherwise, put each character into the current position in the permutation, and make a recursive call
This is a lot shorter in Java:
private static void permutation(char[] perm, int pos, String str) {
if (pos == perm.length) {
System.out.println(new String(perm));
} else {
for (int i = 0 ; i < str.length() ; i++) {
perm[pos] = str.charAt(i);
permutation(perm, pos+1, str);
}
}
}
The caller controls the desired length of permutation by changing the number of elements in perm:
char[] perm = new char[5];
permutation(perm, 0, "abcdefghiklimnop");
Demo.
All permutations of five characters will be contained in the set of the first five characters of every permutation. For example, if you want all two character permutations of a four character string 'abcd' you can obtain them from all permutations:
'abcd', 'abdc', 'acbd','acdb' ... 'dcba'
So instead of printing them in your method you can store them to a list after checking to see if that permutation is already stored. The list can either be passed in to the function or a static field, depending on your specification.
class StringPermutationOfKLength
{
// The main recursive method
// to print all possible
// strings of length k
static void printAllKLengthRec(char[] set,String prefix,
int n, int k)
{
// Base case: k is 0,
// print prefix
if (k == 0)
{
System.out.println(prefix);
return;
}
// One by one add all characters
// from set and recursively
// call for k equals to k-1
for (int i = 0; i < n; i++)
{
// Next character of input added
String newPrefix = prefix + set[i];
// k is decreased, because
// we have added a new character
printAllKLengthRec(set, newPrefix,
n, k - 1);
}
}
// Driver Code
public static void main(String[] args)
{
System.out.println("First Test");
char[] set1 = {'a', 'b','c', 'd'};
int k = 2;
printAllKLengthRec(set1, "", set1.length, k);
System.out.println("\nSecond Test");
char[] set2 = {'a', 'b', 'c', 'd'};
k = 1;
printAllKLengthRec(set2, "", set2.length, k);
}
This is can be easily done using bit manipulation.
private void getPermutation(String str, int length)
{
if(str==null)
return;
Set<String> StrList = new HashSet<String>();
StringBuilder strB= new StringBuilder();
for(int i = 0;i < (1 << str.length()); ++i)
{
strB.setLength(0); //clear the StringBuilder
if(getNumberOfOnes(i)==length){
for(int j = 0;j < str.length() ;++j){
if((i & (1 << j))>0){ // to check whether jth bit is set (is 1 or not)
strB.append(str.charAt(j));
}
}
StrList.add(strB.toString());
}
}
System.out.println(Arrays.toString(StrList.toArray()));
}
private int getNumberOfOnes (int n) // to count how many numbers of 1 in binary representation of n
{
int count=0;
while( n>0 )
{
n = n&(n-1);
count++;
}
return count;
}

Can't change variable while doing recursion

public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5 };
int[] b = new int[5];
rekursiq(a, b, 0, 0, 1);
}
static void rekursiq(int[] a, int[] b, int index, int start, int check) {
if (index == b.length){
System.out.println(java.util.Arrays.toString(b));
} else {
for (int i = start; i < a.length; i++) {
b[index] = a[i];
rekursiq(a, b, index + 1, i + 1, check + 1);
}
}
}
Now my question is: Instead of b.length in the recursion bottom I want to place an int check, and make check go +1 on every going there, and do something.
while (check < b.length) go the if statement, else return; but I can't seem to 1) increase the value properly and 2) make this while correctly. I don't know why.
I think my best try was
static void rekursiq(int[] a, int[] b, int index, int start, int check) {
if (check > b.length) {
return;
} else {
if (index == check) {
System.out.println(java.util.Arrays.toString(b));
} else {
for (int i = start; i < a.length; i++) {
b[index] = a[i];
rekursiq(a, b, index + 1, i + 1, check + 1);
}
}
}
}
But it did not work, and I hope some one of you can tell me why and how to fix it.
The value of check does increase when the method is called recursively. However, the problem you have is independent of check.
The Problem
Let me start by repeating what abhishrp already briefly mentioned: In this particular case, you want to either use a loop to iterate over all elements in the array, or recursion, but not use a loop inside of your recursive method. The reason is the following: At each step in the recursion, you look at exactly one element: the element at position index.
The Solution
So, how would you recursively copy an array? Let us assume you have a source array (in your code a) and an empty destination array (in your code b). Now, we know how to copy a single element of the array, namely destination[index] = source[index], and we can imagine copying the array as copying the first element, and then copying the subarray starting at the second element. Note that knowing how to copy a single element in an array implies knowing how to copy an array containing only one element.
This leads us to the following recursion, which we will turn to code shortly after:
if the given index dereferences the last element in the array, then copy this last element.
otherwise, copy the element at the current index, and copy the subarray starting at the next index.
Or expressed in Java:
static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
if (isIndexOfLastElementInArray(index, destination)) {
destination[index] = source[index];
} else {
destination[index] = source[index];
copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
}
}
static boolean isIndexOfLastElementInArray(int index, int[] array){
return index == array.length - 1;
}
Note that you have too many parameters in your code: The parameter check is really just index, as you want to check whether the index is still inside the bounds of the array. I don't really know what you intended to do with the variable start though - seems like somehow you got confused there because of the loop.
Sidenote
Also, a small justification on why the true-branch of the if-statement in the above code does copy the last element instead of returning nothing if the index is out of bounds as in your code. It's perfectly reasonable to do it like you did. The argument "We trivially know how to copy an empty array" just didn't seem as natural as "knowing how to copy a single element implies knowing how to copy an array consisting of a single element". I encourage you however to adjust the code to "copy an empty array" as a base-case, because it removes the duplication, and more importantly, allows you to copy empty arrays (for which the above implementation would fail horribly).
Code
I also tried to give a comparison between the iterative and the recursive approach:
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
int[] copyOfAUsingIteration = copyArrayUsingIteration(a);
int[] copyOfAUsingRecursion = copyArrayUsingRecursion(a);
assert(Arrays.equals(copyOfAUsingIteration, copyOfAUsingRecursion));
assert(copyOfAUsingIteration != a);
assert(copyOfAUsingRecursion != a);
System.out.println(java.util.Arrays.toString(copyOfAUsingIteration));
System.out.println(java.util.Arrays.toString(copyOfAUsingRecursion));
}
static int[] copyArrayUsingIteration(int[] arrayToCopy) {
int[] result = new int[arrayToCopy.length];
for(int index = 0; index < result.length; index++){
result[index] = arrayToCopy[index];
}
return result;
}
static int[] copyArrayUsingRecursion(int[] arrayToCopy){
if (arrayToCopy.length == 0){
return new int[0];
} else {
int[] result = new int[arrayToCopy.length];
copyValuesFromSourceToDestinationStartingAtIndex(arrayToCopy, result, 0);
return result;
}
}
static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
if (isIndexOfLastElementInArray(index, destination)) {
destination[index] = source[index];
} else {
destination[index] = source[index];
copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
}
}
static boolean isIndexOfLastElementInArray(int index, int[] array){
return index == array.length - 1;
}
To copy one array to another you can use either iteration or recursion. There is no need to do both. By this I mean there is no need for the for loop inside the rekursiq method.

Understanding function to generate parentheses

I have this algorithm to generate all combinations of well-formed parentheses.
Can someone explain the core concept of the algorithm? I tried debugging through it, but I still can't seem to grasp the underlying concept behind the algorithm.
Additionally, any general advice for how one can come up with such an algorithm for this problem, i.e how did one even get so clever to solve it this way, or what practice one has to do to reach this stage.
Problem:
Given n pairs of parentheses, write a function to generate
all combinations of well-formed parentheses. For example, given n = 3, a solution set is:
“((()))”, “(()())”, “(())()”, “()(())”, “()()()”
Code:
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> solutions = new ArrayList<String>();
recursion(n, new String(), solutions);
return solutions;
}
private void recursion(int n, String str, ArrayList<String> sol) {
if(str.length() == 2 * n)
sol.add(str);
else {
int left = 0;
int right = 0;
for(int i = 0; i < str.length(); ++i) {
if(str.charAt(i) == '(')
left++;
if(str.charAt(i) == ')')
right++;
}
if(left == right)
recursion(n, str + "(", sol);
else if(right < left) {
if(left < n)
recursion(n, str + "(", sol);
recursion(n, str + ")", sol);
}
}
}
It helps me to see visually how the calls are being stacked. I added a parameter String depth to the call and printed out depth + str on each call, adding four spaces to each depth parameter for a new call. This gives us a good view of the call order.
Here's the code for it:
recursion(3, new String(), solutions, "");
//...
private static void recursion(int n, String str, ArrayList<String> sol, String depth) {
System.out.println(depth + str);
//...
if(left == right)
recursion(n, str + "(", sol, depth + " ");
else if(right < left) {
if(left < n)
recursion(n, str + "(", sol, depth + " ");
recursion(n, str + ")", sol, depth + " ");
}
And here's what it prints out:
(
((
(((
((()
((())
((()))
(()
(()(
(()()
(()())
(())
(())(
(())()
()
()(
()((
()(()
()(())
()()
()()(
()()()
Each level of recursion adds another indent to the output. If two outputs are at the same level of indentation, then they were both called from the same level of recursion.
Here's another visual:
Note that each node is a deeper level of recursion and each time a child node comes straight down out of a parent node, it doesn't split into two recursive paths. That is, the parent node only calls recursion once.
Recursion can definitely mess with your head. Here's another approach which might be easier to follow:
void generate() {
ArrayList<String> results = new ArrayList<String>();
generateParentheses(4, 0, new StringBuilder(), results);
System.out.println(results);
}
void generateParentheses(final int remaining, final int openCount, final StringBuilder s, final List<String> results) {
if (remaining == 0 && openCount == 0) {
results.add(s.toString());
return;
}
if (openCount > 0) { // we can close the open one
s.append(")");
generateParentheses(remaining, openCount-1, s, results);
s.setLength(s.length()-1); // pop the last char off
}
if (remaining > 0) { // start a new one
s.append("(");
generateParentheses(remaining-1, openCount+1, s, results);
s.setLength(s.length()-1); // pop the last char off
}
}
Output is [()()()(), ()()(()), ()(())(), ()(()()), ()((())), (())()(), (())(()), (()())(), (()()()), (()(())), ((()))(), ((())()), ((()())), (((())))]
This goes at the problem from the other end. How do you come up with these patterns?
Start with the number of pairs (remaining).
There are only two possibilities: open or closed. An open parentheses can only be appended if there are some remaining to append. A close parentheses can only be appended if there is a corresponding opening parentheses to close.
So you just need to keep a count of how many remaining you have, and how deep into parentheses you are. Let recursion handle the rest.
Here's my attempted breakdown of the provided algorithm:
if(str.length() == 2 * n)
sol.add(str);
You know you're done if the string length is twice the number of pairs of parentheses. Why?
Because each pair of parentheses is 2 characters long, having n pairs of parentheses means you have 2 * n characters total (i.e. length / 2 == number of parentheses)
int left = 0;
int right = 0;
for(int i = 0; i < str.length(); ++i) {
if(str.charAt(i) == '(')
left++;
if(str.charAt(i) == ')')
right++;
}
This loops through the string character by character and does some tests and changes left and right depending on whether the particular character is a opening or closing parentheses. Based on that, can you figure out what left and right are at the end of the loop?
left and right are the number of opening/closing parentheses in the string, respectively
if(left == right)
recursion(n, str + "(", sol);
else if(right < left) {
if(left < n)
recursion(n, str + "(", sol);
recursion(n, str + ")", sol);
}
If left == right, then you call the same function, except you tack on an opening parenthesis onto the existing string. Why add a parenthesis, and why is it an opening parenthesis?
You know you're not done, because if you were you would have triggered the first if statement. Because adding a closed parenthesis would result in ill-formed parenthesis because there is no unclosed opening parenthesis (remember, left == right), the next logical step is to add an opening parenthesis.
If right < left, you know that you have at least one unclosed opening parenthesis. So you want to do another check.
if(left < n)
recursion(n, str + "(", sol)
Why do this check? If left < n, then you know that if you close all the open parentheses you won't have enough pairs (n pairs of parentheses have n opening parentheses). So might as well add another opening parenthesis!
The last statement has an implicit else associated with it. If left is not < n, then you know adding another left parenthesis would put you over the requested number of pairs. So add a closing parenthesis and continue.
The core concept:
1)X:If a string has more closing parentheses than opening ones, adding more parentheses to the right won't make it a well-formed combination.
2)All well-formed combinations have equal number of opening and closing parentheses. Hence, each type can be found exactly n times
3)If the number of closing ones is less than the number of the opening ones, then we can always make a consequence well-formed, by adding more closing parentheses.
This algorithm builds the combination, adding new symbols to the right
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> solutions = new ArrayList<String>();
recursion(n, new String(), solutions);
return solutions;
}
private void recursion(int n, String str, ArrayList<String> sol) {
//If we got a sting long enough, we return it. This means a) We generate all
//strings only once. b)If a string of length 2*n is created, then it is correct. Other
//code should satisfy these conditions
if(str.length() == 2 * n)
sol.add(str);
else {
int left = 0;
int right = 0;
for(int i = 0; i < str.length(); ++i) {
if(str.charAt(i) == '(')
left++;
if(str.charAt(i) == ')')
right++;
}
//left and right are now numbers of parentheses in the string.
//Opening and closing respectively.
if(left == right)//On each step we maintain the condition X
//that the number of closing brackets is less or equal to the number of opening.
//Therefore, is their numbers are equal we can only add opening ones
recursion(n, str + "(", sol);
else if(right < left) { // if X is maintained and we can add
//both types
if(left < n)// The number of opened should be no more than n,
//according to 2)
recursion(n, str + "(", sol);
recursion(n, str + ")", sol);//The number of closing ones is
//limited by X by the number of opening ones, which is limited by n => the number of
//the closed ones is limited by n => we can add them as long as it doesn't violate X
}
}
}
I wrote my own recursive parentheses generator in a different style. It basically builds up a String, but at each recursive call, a new String is created so that the backtracking is correct. I hope someone finds it helpful.
import java.util.ArrayList;
import java.util.List;
public class GenerateParentheses {
// N: The max number of matching parentheses. This value does not change.
// usedL, usedR : Number of left and right parentheses already used in 'current' string.
// current: the current string being built.
// depth: recursion depth, used for pretty-printing
public static void generate(int N, int usedL, int usedR, String current, List<String> result, int depth) {
System.out.printf("%susedL=%d, usedR=%d, current='%s'\n",
getIndentation(depth), usedL, usedR, current);
if (usedL == N && usedR == N) {
// We've used up all the available parentheses (up to N),
// so add the current built string to the result.
result.add(current);
return;
}
if (usedL < N) {
// Add another left parenthesis "(".
String newCurrent = current + "(";
generate(N, usedL + 1, usedR, newCurrent, result, depth+1);
}
if (usedR < N && usedL > usedR) {
// Add another right parenthesis ")" if there are already
// used left parentheses.
String newCurrent = current + ")";
generate(N, usedL, usedR + 1, newCurrent, result, depth+1);
}
}
// Utility function used for pretty-printing.
private static String getIndentation(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append(" ");
}
return sb.toString();
}
public static void main(String argv[]) {
int N = 3;
int usedL = 0;
int usedR = 0;
String current = "";
List<String> result = new ArrayList<String>();
int depth = 0;
generate(N, usedL, usedR, current, result, depth);
for (String s : result) {
System.out.printf("%s\n", s);
}
}
}
Here is the output:
usedL=0, usedR=0, current=''
usedL=1, usedR=0, current='('
usedL=2, usedR=0, current='(('
usedL=3, usedR=0, current='((('
usedL=3, usedR=1, current='((()'
usedL=3, usedR=2, current='((())'
usedL=3, usedR=3, current='((()))'
usedL=2, usedR=1, current='(()'
usedL=3, usedR=1, current='(()('
usedL=3, usedR=2, current='(()()'
usedL=3, usedR=3, current='(()())'
usedL=2, usedR=2, current='(())'
usedL=3, usedR=2, current='(())('
usedL=3, usedR=3, current='(())()'
usedL=1, usedR=1, current='()'
usedL=2, usedR=1, current='()('
usedL=3, usedR=1, current='()(('
usedL=3, usedR=2, current='()(()'
usedL=3, usedR=3, current='()(())'
usedL=2, usedR=2, current='()()'
usedL=3, usedR=2, current='()()('
usedL=3, usedR=3, current='()()()'
((()))
(()())
(())()
()(())
()()()
How you get to the solution will be easier to see as you get more experience with recursion.
Idea: well-formed parentheses are always going to start with a left paren, have an equal number of left & right, and when reading left to right the following will always be true left >= right
Therefore when making a recursive solution, we'll use a simple rule: prefer to open left paren and let the nature of the recursive function unwinding take care of the rest
private void recursion(int n, String str, ArrayList<String> sol) {
if(str.length() == 2 * n)
sol.add(str);
We have n pairs, add the solution & return
else {
int left = 0;
int right = 0;
for(int i = 0; i < str.length(); ++i) {
if(str.charAt(i) == '(')
left++;
if(str.charAt(i) == ')')
right++;
}
Count up the number of left & right parens
if(left == right)
recursion(n, str + "(", sol);
str is currently balanced & since we prefer left over right, add a left
else if(right < left) {
This could just be an else, right will never be > left. Either way, it means that we're currently unbalanced, there is at least 1 more left than right.
if(left < n)
recursion(n, str + "(", sol);
Check if you can add another left, again because prefer left over right
recursion(n, str + ")", sol);
}
}
Add our right paren. This will either close the paren added in the line above it, or if that wasn't executed, it will close an earlier left (remember that we're in this block because it's currently unbalanced)
Here's a more simpler and intuitive solution to your problem.
Again, this follows the recursion idea but it is easier to read and more efficient than the one you posted.
public void generateParantheses(int n){
helper(n,0,0,"");
}
public void helper(int n, int open, int close, String result){
if(result.length()==2*n) {
// easy enough to understand? one open and one close for each n?
System.out.println(result);
return;
}
if(open<n){
//start off with all n open parantheses
helper(n, open+1, close, result+"(" );
}
if(close<open){
// now check if we can add closing parantheses on top of open in this condition
helper(n, open, close+1, result+")");
}
}
public static void findParenthisis(String s , int left ,int right){
if(left==right && left == 0){
System.out.println(s);
}
if(left > 0){
findParenthisis(s+'(',left-1,right);
}
if(left < right){
findParenthisis(s + ')',left,right-1);
}
}
void generateParenthesis(int open, int close, int position, int n, char[] str) {
/*
* open = open parenthesis
* close = close parenthesis
* position = 2*n (length of combination of valid parenthesis
* n = pair of parenthesis
* Algorithm:
* 1.Check if position == 2*n -- Yes, print the str
* 2.check if open is less than n
* If true, add a open parenthesis into str and call the function recursively by
* incrementing open by 1 and position by 1
* 3.check if close < open
* If true , add a close parenthesis and call the function recursively by
* incrementing close by 1 and position by 1*/
if(position ==str.length) {
for(int i=0;i<str.length;i++) {
System.out.print(str[i]);
}
System.out.println();
return;
}
if(open < n) {
str[position] = '(';
generateParenthesis(open+1,close,position+1,n,str);
}if(close< open) {
str[position]=')';
generateParenthesis(open,close+1,position+1,n,str);
}
}
I think I found a very intuitive solution that gets inspiration from a similar problem. Imagine you have a grid of size n x n. You want to move from the left-down corner to the right-upper corner. Every move to the right can be interpreted as a ( and every move up as ). The simplest case would be a grid of 1x1. There are two ways to go: RU (right then up) and UR (up then right) the first one corresponds to () and the second one )(. The second case is invalid so we discard all the paths from the upper triangle of the grid. For n=4 :
The problem can be solved recursively. We should start from R=0, U=0. Once we get to R=n, U=n we are done and should add the partial_solution to the solutions. There are two cases:
When R<n we still can move right and increment R.
When U<R notice we can only go up as much as we stay under the diagonal. In this case we can still move up and increment U.
def move(R, U, n, solutions, partial_solution):
if R == n and U == n:
solutions.append(partial_solution)
return
if R < n:
move(R + 1, U, n, solutions, partial_solution + '(')
if U < R:
move(R, U + 1, n, solutions, partial_solution + ')')
solutions = []
n=4
move(0, 0, n, solutions, '')
print(solutions)
Additional:
Note that this formulation also helps us to understand the number of ways we can form the parenthesis. Going from R=0, U=0 to R=n, U=n requires a string of R's and U's with the property that we should have exactly n R's and n U's. For example for n=3:
RRRUUU, RRURUU, URURUR, URRRUU, ...
It's a combinatorial problem and the number of ways is combination(2n, n). But we have to consider removing the upper triangle. This leaves us with 1/(n+1) * combination(2n, n) which is the Catalan number of n.
`class Solution:
def generateParenthesis(self, n):
# Backtracking
result_list = list()
stack = list()
def create_parenthesis(left_count, right_count):
if left_count == n and right_count == n:
result_list.append("".join(stack))
if left_count < n:
print("Appending ( to stack")
stack.append("(")
before_spacing = (left_count + right_count) * "\t"
print(before_spacing + "".join(stack))
create_parenthesis(left_count+1, right_count)
print("Popping from left_count < n")
stack.pop()
if left_count > right_count:
print("Appending ) to stack.")
stack.append(")")
before_spacing = (left_count + right_count) * "\t"
print(before_spacing + "".join(stack))
create_parenthesis(left_count, right_count+1)
print("Popping from left_count > right_count")
stack.pop()
create_parenthesis(0, 0)
return result_list`
print(Solution().generateParenthesis(n=3))
Output:
output
class Solution:
def generateParenthesis(self, n: int) -> list[str]:
stack = []
res = []
def back_Move(openPar,closedPar):
if openPar == closedPar==n:
res.append("".join(stack))
return
if openPar<n:
stack.append("(")
back_Move(openPar+1,closedPar)
stack.pop()
if closedPar<openPar:
stack.append(")")
back_Move(openPar,closedPar+1)
stack.pop()
back_Move(0,0)
return res

How to reverse an array of strings recursively?

supposed to reverse an array of strings recursively.
having trouble implementing this. if i was using a for loop i would just start it at the end of the array and print out the array starting with the last element and ending with the first.
I'm not too sure how to do it recursively. i was thinking about using a swap but that idea sort of fizzled when i couldnt figure out how to change the elements that i was swapping.
any ideas or a push in the right direction would be appreciated.
this is what icame up with so far. i know its wrong, i get an error out of bounds exception which im not sure how to fix. I think im not swapping the first and last correctly. but am i getting the right idea?
this is what i came up with.
a is an array. its inside a class.
// reverse an array
public void rev()
{
rev(0,a.length-1);
}
private void rev(int first, int last)
{
if(last == 0)
{
//do nothing
}
else
{
while(first != last)
{
int temp = first;
first = last;
last = temp;
System.out.print(" " + a[first]);
rev((first + 1), (last - 1));
}
}
}
made some changes and it reverses the last 3 elements but the it repeats the second element. i have no if statement that controls when it runs so shouldnt it run until left = right?
this is what i changed it to
// reverse an array
public void rev()
{
rev(0,a.length-1);
}
private void rev(int first, int last)
{
if(last == 0)
{
//do nothing
}
else
{
String temp = a[first];
a[first] = a[last];
a[last] = temp;
System.out.print(" " + a[first]);
rev(first+ 1, last-1);
}
}
The trick with recursion is to try and think of the problem in terms of a base case and then a way to reduce everything to that base case.
So, if you're trying to reverse a list then you can think of it like this:
The reverse of a list of size 1 is that list.
For a list of size > 1 then the first element in the output list will be the last element of the input list.
The rest of the output list will be the reverse of the input list, minus the last element.
You now have your recursive definition.
Hope that helps.
the while loop is too much, since you are using recursion anyway, try it like this
private void rev(int first, int last)
{
if(first < last)
{
var temp = a[first];
a[first] = a[last];
a[last] = temp;
rev(first + 1, last - 1);
}
}
I always like having a simple public method that calls the private recursive one. That way from other places in your code you just give it the array, and don't have to worry about the other arguments. Also, this catches empty arrays, but you would still need to check for null at some point near the start. Maybe throw an exception in the public method if the array is null?
public String[] reverseArray(String[] theArray) {
this.reverseArrayWorker(theArray, 0, theArray.length -1);
}
private String[] reverseArrayWorker(String[] theArray, int left, int right) {
// Check your base cases first
if (theArray.length <= 1) {
// Array is one element or empty
return theArray;
} else if (left - right <= 0) {
// If there are an odd # of items in the list you hit the center
// If there are an even number your indexes past each other
return theArray;
}
// Make the recursive call
this.reverseArrayWorker(theArray, left + 1, right - 1);
// Switch the two elements at this level
String temp = theArray[left];
theArray[left] = theArray[right];
theArray[right] = temp;
// Return the array up a level
return theArray;
}
public int[] reverse(int[] returnMe, int[] original, int curPos){
if (original.length == 1){
return original;
}else{
if (curPos < original.length){
returnMe[curPos] = original[original.length - 1 - curPos];
reverse(returnMe, original, curPos + 1);
}else{
return returnMe;
}
}
}
Here is an example (but without A String since it is homework) but hopefully it will give you the idea.
public static List<Character> reverse(List<Character> chars) {
return chars.isEmpty() ? chars :
addToList(chars.get(0), reverse(chars.subList(1, chars.length()));
}
public static T List<T> addToList(T t, List<T> ts) {
List<T> ret = new ArrayList<T>();
ret.addAll(ts);
ret.add(t);
return ret;
}
This will work too. Kinda Lisp-like solution.
public static List<String> append(String x, List<String> xs) {
xs.add(x);
return xs;
}
public static List<String> reverse(List<String> xs) {
return xs.isEmpty()
? xs
: append(xs.get(0), reverse(xs.subList(1, xs.size())));
}
I/O:
List ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Reversed list ==> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Categories

Resources