Minimum number of swap of operator to complement expression tree evaluation - algorithm

I have an expression tree where each leaf node contains 0 or 1 as value, and all the internal nodes contain "&" or "||" as operator. Now I need to evaluate the tree; the result will be either 0 or 1.
The question is minimum number of swap of internal node required to complement the result of original expression tree. Any internal node can be flipped; e.g. if it is a "&", we can make it "||", and vice versa.
To solve this I tried the following technique but I didn't succeed in it:
My approach was that I would check the root whether it is a "&" or "||" operator and whether the result of evaluation tree 0 or 1, depending on that I went forward with the evaluation.

i'm not sure if i understood you question. if it's how do evaluate the whole tree my answer is:
try a recursion.
something like this:
evalute() {
if_the_root_is_an_operator() {
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}
optimizations could be, to check if l or r are values, and skip the evaluation if their values already define the final result.
"0 AND (subtree)" is surely 0,
"1 OR (subtree)" is 1, so subtree doesn't need to be evaluated
evalute() {
if (the_root_is_an_operator()) {
if ( operator_is_and() &&
(left_is_leaf() && value(left)==0) ||
(right_is_leaf() && value(right)==0))
return 0;
if ( operator_is_or() &&
(left_is_leaf() && value(left)==1) ||
(right_is_leaf() && value(right)==1))
return 1;
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}

This is an example of problem asked in question.
OR
/ \
OR AND
/ \ / \
1 0 1 1
Output is 1. Need to found min numbers of operands to be changed to change the output to 0.
Min number of operators required to be changed are 2.
class A {
int min=Integer.max;
int minNumber(Tree node) {
if(node==null) return Math.max;
if(node.left==null && node.right==null) return Math.max;
String c = node.data;
int l = evaluate(node.left);
int r = evaluate(node.right);
if(l || r==0) { min_number = 1; }
else {
if(l && r == 1 )
{
min_number = 0;
}
else if(l && r == 0)
{
min_number = 0;
}
int left = min_number + minNumber(node.left)
int right = min_number + minNumber(node.right);
min_number = Math.min(left,right);
}
if(min_number<min) min = min_number; return min;
}

Related

Number of Nodes in binary tree having only left child

How to find Number of Nodes in binary tree having only left child?
LeftNode(root)
{
if(root==NULL)
return 0;
if(root->left!=null && root-right==null)
return (1+LeftNode(root->left));
return (LeftNode (root->left) + LeftNode (root->right))
}
I would do so (C++):
int leftNode(Node * root)
{
if (root == nullptr)
return 0;
// c is 1 if root has a left child and has not a right one
int c = root->left != nullptr and root->right == nullptr ? 1 : 0;
return c + leftNode(root->left) + leftNode(root->right);
}
Since no specific language is required I am going to write my solutions in Swift
func nodesWithOnlyLeftChild(node:Node?) -> UInt {
guard let node = node else { return 0 }
let count: Uint = (node.left != nil && node.right == nil) ? 1 : 0
return nodesWithOnlyLeftChild(node.left) + nodesWithOnlyLeftChild(node.right) + count
}
Explaination
1: The signature
func nodesWithOnlyLeftChild(node:Node?) -> UInt
The function accepts a parameter of type Node?. This does mean the parameter can be a Node or nil.
The function does return an unsigned integer.
2: Checking the parameter
guard let node = node else { return 0 }
The first line verify that the input param is not nil. If it is not nil then the next line is executed, otherwise 0 is returned.
3: Evaluating the current node
let count: UInt = (node.left != nil && node.right == nil) ? 1 : 0
The constant count is created. It is populated with 1 if this node has only a left child. 0 otherwise.
4: Recursive calls
return nodesWithOnlyLeftChild(node.left) + nodesWithOnlyLeftChild(node.right) + count
The function does return the result of nodesWithOnlyLeftChild applied to the left child + nodesWithOnlyLeftChild applied to the right child + the constant count
Considerations
The time complexity of this function is O(n) where n is the nodes in the three.
The space complexity is O(1).
Infact although we can have max n recursive calls, the Tail Recursion (supported by LLVM and other compilers) does use the same stack frame when some conditions are met.

valid 0 and 1 String recursion

I want to write a recursive algorithm that evaluates a string of ones and zeros and determines if the string is valid. The string is invalid if the string contains 3 zeroes in a row.
For example :
1010010001 invalid
1111101101 valid
1000111101 invalid
I have no idea how to write this algorithm. Thank you for any help.
You can do something like this ( assuming str is your string and n is its length and indexing is 0 based )
func ( index )
if index >= n
return true
if index < 2
return func(index+1)
if str[index] is 0 and str[index-1] is 0 and str[index-2] is 0
return false
return func(index+1)
// call func(0) , assuming str is global , also answer is boolean
answer = func(0)
Time complexity is O(n). Just for completeness for such a strightforward
thing I would just write it iteratively using a loop.
//This is in c/c++
bool answer = true;
for(i = 2;i < n;i++)
{
if(str[i] == '0' && str[i-1] == '0' && str[i-2] == '0')
answer = false;
}
public static boolean isValid(String s){
return isValidInt(s)==3;
}
private static int isValidInt(String s){
if( s == null || s.length() ==0)
return 0;
int prevSum=isValidInt(s.substring(1));
if( prevSum == 3 )
return 3;
return s.charAt(0) != '0' ?0:1+prevSum;
}

Binary search for the closest value less than or equal to the search value

I'm trying to write an algorithm for finding the index of the closest value that is lesser than or equal to the search value in a sorted array. In the example of the array [10, 20, 30], the following search values should output these indexes:
searchValue: 9, index: -1
searchValue: 10, index: 0
searchValue: 28, index: 1
searchValue: 55555, index: 2
I want to use binary search for logarithmic runtime. I have an algorithm in C-esque psuedocode, but it has 3 base cases. Can these 3 base cases be condensed into 1 for a more elegant solution?
int function indexOfClosestLesser(array, searchValue, startIndex, endIndex) {
if (startIndex == endIndex) {
if (searchValue >= array[startIndex]) {
return startIndex;
} else {
return -1;
}
}
// In the simplistic case of searching for 2 in [0, 2], the midIndex
// is always 0 due to int truncation. These checks are to avoid recursing
// infinitely from index 0 to index 1.
if (startIndex == endIndex - 1) {
if (searchValue >= array[endIndex]) {
return endIndex;
} else if (searchValue >= array[startIndex]) {
return startIndex;
} else {
return -1;
}
}
// In normal binary search, this would be the only base case
if (startIndex < endIndex) {
return -1;
}
int midIndex = endIndex / 2 + startIndex / 2;
int midValue = array[midIndex];
if (midValue > searchValue) {
return indexOfClosestLesser(array, searchValue, startIndex, midIndex - 1);
} else if (searchValue >= midValue) {
// Unlike normal binary search, we don't start on midIndex + 1.
// We're not sure whether the midValue can be excluded yet
return indexOfClosestLesser(array, searchValue, midIndex, endIndex);
}
}
Based on your recursive approach, I would suggest the following c++ snippet that reduces the number of different cases a bit:
int search(int *array, int start_idx, int end_idx, int search_val) {
if( start_idx == end_idx )
return array[start_idx] <= search_val ? start_idx : -1;
int mid_idx = start_idx + (end_idx - start_idx) / 2;
if( search_val < array[mid_idx] )
return search( array, start_idx, mid_idx, search_val );
int ret = search( array, mid_idx+1, end_idx, search_val );
return ret == -1 ? mid_idx : ret;
}
Basically it performs a normal binary search. It only differs in the return statement of the last case to fulfill the additional requirement.
Here is a short test program:
#include <iostream>
int main( int argc, char **argv ) {
int array[3] = { 10, 20, 30 };
std::cout << search( array, 0, 2, 9 ) << std::endl;
std::cout << search( array, 0, 2, 10 ) << std::endl;
std::cout << search( array, 0, 2, 28 ) << std::endl;
std::cout << search( array, 0, 2, 55555 ) << std::endl;
return 0;
}
The output is as desired:
-1
0
1
2
Frankly speaking, I find the logic of finding a number greater than a given number a lot easier than the logic needed to find numbers less than or equal to a given number. Obviously, the reason behind that is the extra logic (that forms the edge cases) required to handle the duplicate numbers (of given num) present in the array.
public int justGreater(int[] arr, int val, int s, int e){
// Returns the index of first element greater than val.
// If no such value is present, returns the size of the array.
if (s >= e){
return arr[s] <= N ? s+1 : s;
}
int mid = (s + e) >> 1;
if (arr[mid] < val) return justGreater(arr, val, mid+1, e);
return justGreater(arr, val, s, mid);
}
and then to find the index of the closest value that is lesser than or equal to the search value in a sorted array, just subtract the returned value by 1:
ans = justGreater(arr, val, 0, arr.length-1) - 1;
Trick
The trick here is to search for searchValue + 1 and return the the found index as index - 1 which is left - 1 in the code below
For example if we search for 9 in [10, 20, 30]. The code will look for 10 and return that it's present at 0th index and we return 0-1 which is -1
Similarly if we try to search for 10 in the above example it will search for 10 + 1 and return 1st index and we return 1-1 which is 0
Code
def binary_search(array, searchValue, startIndex=0, endIndex=2 ** 32):
"""
Binary search for the closest value less than or equal to the search value
:param array: The given sorted list
:param searchValue: Value to be found in the array
:param startIndex: Initialized with 0
:param endIndex: Initialized with 2**32
:return: Returns the index closest value less than or equal to the search value
"""
left = max(0, startIndex)
right = min(len(array), endIndex)
while left < right:
mid = (left + right) // 2
if array[mid] < searchValue + 1:
left = mid + 1
else:
right = mid
return left - 1
It can also be done in a single line with the standard library.
import bisect
def standard_binary_search(array, searchVal):
return bisect.bisect_left(array, searchVal + 1) - 1
Testing
Testing the test cases provided by OP
array = [10, 20, 30]
print(binary_search(array, 9))
print(binary_search(array, 10))
print(binary_search(array, 28))
print(binary_search(array, 5555))
Results
-1
0
1
2
I created a linear search to test the binary search.
def linear_search(array, searchVal):
ans = -1
for i, num in enumerate(array):
if num > searchVal:
return ans
ans = i
return ans
And a function to test all the binary search functions above.
Check for correctness
def check_correctness(array, searchVal):
assert binary_search(array, searchVal) == linear_search(array, searchVal)
assert binary_search(array, searchVal) == standard_binary_search(array, searchVal)
return binary_search(array, searchVal)
Driver Function
nums = sorted(
[460, 4557, 1872, 2698, 4411, 1730, 3870, 4941, 77, 7789, 8553, 6011, 9882, 9597, 8060, 1518, 8210, 380, 6822, 9022,
8255, 8977, 2492, 5918, 3710, 4253, 8386, 9660, 2933, 7880, 615, 1439, 9311, 3526, 5674, 1899, 1544, 235, 3369,
519, 8018, 8489, 3093, 2547, 4903, 1836, 2447, 570, 7666, 796, 7149, 9623, 681, 1869, 4381, 2711, 9882, 4348, 4617,
7852, 5897, 4135, 9471, 4202, 6630, 3037, 9694, 9693, 7779, 3041, 3160, 4911, 8022, 7909, 297, 7258, 4379, 3216,
9474, 8876, 6108, 7814, 9484, 2868, 882, 4206, 3986, 3038, 3659, 3287, 2152, 2964, 7057, 7122, 261, 2716, 4845,
3709, 3562, 1928]
)
for num in range(10002):
ans = check_correctness(nums, num)
if ans != -1:
print(num, nums[check_correctness(nums, num)])
The driver function ran without any assert errors. This proves the correctness of the above two functions.
Commented version in typescript. Based on this answer but modified to return less than or equal to.
/**
* Binary Search of a sorted array but returns the closest smaller value if the
* needle is not in the array.
*
* Returns null if the needle is not in the array and no smaller value is in
* the array.
*
* #param haystack the sorted array to search #param needle the need to search
* for in the haystack #param compareFn classical comparison function, return
* -1 if a is less than b, 0 if a is equal to b, and 1 if a is greater than b
*/
export function lessThanOrEqualBinarySearch<T>(
haystack: T[],
needle: T,
compareFn: (a: T, b: T) => number
): T | null {
let lo = 0;
let hi = haystack.length - 1;
let lowestFound: T | null = null;
// iteratively search halves of the array but when we search the larger
// half keep track of the largest value in the smaller half
while (lo <= hi) {
let mid = (hi + lo) >> 1;
let cmp = compareFn(needle, haystack[mid]);
// needle is smaller than middle
// search in the bottom half
if (cmp < 0) {
hi = mid - 1;
continue;
}
// needle is larger than middle
// search in the top half
else if (cmp > 0) {
lo = mid + 1;
lowestFound = haystack[mid];
} else if (cmp === 0) {
return haystack[mid];
}
}
return lowestFound;
}
Here's a PHP version, based on user0815's answer.
Adapted it to take a function, not just an array, and made it more efficient by avoiding evaluation of $mid_idx twice.
function binarySearchLessOrEqual($start_idx, $end_idx, $search_val, $valueFunction)
{
//N.B. If the start index is bigger or equal to the end index, we've reached the end!
if( $start_idx >= $end_idx )
{
return $valueFunction($end_idx) <= $search_val ? $end_idx : -1;
}
$mid_idx = intval($start_idx + ($end_idx - $start_idx) / 2);
if ( $valueFunction($mid_idx) > $search_val ) //If the function is too big, we search in the bottom half
{
return binarySearchLessOrEqual( $start_idx, $mid_idx-1, $search_val, $valueFunction);
}
else //If the function returns less than OR equal, we search in the top half
{
$ret = binarySearchLessOrEqual($mid_idx+1, $end_idx, $search_val, $valueFunction);
//If nothing is suitable, then $mid_idx was actually the best one!
return $ret == -1 ? $mid_idx : $ret;
}
}
Rather than taking an array, it takes a int-indexed function. You could easily adapt it to take an array instead, or simply use it as below:
function indexOfClosestLesser($array, $searchValue)
{
return binarySearchLessOrEqual(
0,
count($array)-1,
$searchValue,
function ($n) use ($array)
{
return $array[$n];
}
);
}
Tested:
$array = [ 10, 20, 30 ];
echo "0: " . indexOfClosestLesser($array, 0) . "<br>"; //-1
echo "5: " . indexOfClosestLesser($array, 5) . "<br>"; //-1
echo "10: " . indexOfClosestLesser($array, 10) . "<br>"; //0
echo "15: " . indexOfClosestLesser($array, 15) . "<br>"; //0
echo "20: " . indexOfClosestLesser($array, 20) . "<br>"; //1
echo "25: " . indexOfClosestLesser($array, 25) . "<br>"; //1
echo "30: " . indexOfClosestLesser($array, 30) . "<br>"; //2
echo "35: " . indexOfClosestLesser($array, 35) . "<br>"; //2
Try using a pair of global variables, then reference those variables inside the COMPARE function for bsearch
In RPGIV we can call c functions.
The compare function with global variables looks like this:
dcl-proc compInvHdr;
dcl-pi compInvHdr int(10);
elmPtr1 pointer value;
elmPtr2 pointer value;
end-pi;
dcl-ds elm1 based(elmPtr1) likeds(invHdr_t);
dcl-ds elm2 based(elmPtr2) likeds(elm1);
dcl-s low int(10) inz(-1);
dcl-s high int(10) inz(1);
dcl-s equal int(10) inz(0);
select;
when elm1.rcd.RECORDNO < elm2.rcd.RECORDNO;
lastHiPtr = elmPtr2;
return low;
when elm1.rcd.RECORDNO > elm2.rcd.RECORDNO;
lastLoPtr = elmPtr2;
return high;
other;
return equal;
endsl;
end-proc;
Remember, that in bsearch the first element is the search key and the second element is the actual storage element in your array/memory, that is why the COMPARE procedure is using elmPtr2;
the call to bsearch looks like this:
// lastLoPtr and LastHiPtr are global variables
// basePtr points to the beginning of the array
lastLoPtr = basePtr;
lastHiPtr = basePtr + ((numRec - 1) * sizRec));
searchKey = 'somevalue';
hitPtr = bsearch(%addr(searchkey)
:basePtr
:numRec
:sizRec
:%PADDR('COMPINVHDR'));
if hitPtr <> *null;
//? not found
hitPtr = lastLoPtr;
else;
//? found
endif;
So if the key is not found then the hitPtr is set to the key of the closest match, effectively archiving a "Less than or Equal key".
If you want the opposite, the next greater key. Then use lastHiPtr to reference the first key greater than the search key.
Note: protect the global variables against race conditions (if applicable).
Wanted to provide a non-binary search way of doing this, in C#. The following finds the closest value to X, without being greater than X, but it can be equal to X. My function also does not need the list to be sorted. It is also theoretically faster than O(n), but only in the event that the exact target number is found, in which case it terminates early and returns the integer.
public static int FindClosest(List<int> numbers, int target)
{
int current = 0;
int difference = Int32.MaxValue;
foreach(int integer in numbers)
{
if(integer == target)
{
return integer;
}
int diff = Math.Abs(target - integer);
if(integer <= target && integer >= current && diff < difference)
{
current = integer;
difference = diff;
}
}
return current;
}
I tested this with the following setup, and it appears to be working flawlessly:
List<int> values = new List<int>() {1,24,32,6,14,9,11,22 };
int target = 21;
int closest = FindClosest(values,target);
Console.WriteLine("Closest: " + closest);
7 years later, I hope to provide some intuition:
If search_val <= arr[mid], we know for the sure that the solution resides in the interval [lo, mid], inclusive. So, we set right=mid (we probably can set right=mid-1 if mid is not included). Note that if search_val < arr[mid], we in fact know that the solution resides in [lo, mid), mid not inclusive. This is because search_val won't fall back on mid and use mid as the closest value <= search value if it is less than arr[mid].
On the other hand, search_val >= arr[mid]. In this case, we know that the solution resides in [mid, hi]. In fact, even if search_val > arr[mid], the solution is still [mid, hi]. This means that we should set left = mid. HOWEVER, in binary search, left is usually always set to mid + 1 to avoid infinite loops. But this means, when the loops at left==right, it is possible we are 1 index over the solution. Thus, we do a check at the very end to return either the left or left-1, that you can see in the other solutions.
Practice Problem: Search a 2D Matrix
Write an efficient algorithm that searches for a value target in an m x n integer matrix matrix. This matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the
previous row.
The smart solution to this problem is to treat the two-dimensional array as an one-dimensional one and use regular binary search. But I wrote a solution that first locates the correct row. The process of finding the correct row in this problem is basically the same as finding the closest value less than equal to the search value.
Additionally link on binary search: Useful Insights into Binary Search
a non-recursive way using loop, I'm using this in javascript so I'll just post in javascript:
let left = 0
let right = array.length
let mid = 0
while (left < right) {
mid = Math.floor((left + right) / 2)
if (searchValue < array[mid]) {
right = mid
} else {
left = mid + 1
}
}
return left - 1
since general guideline tells us to look at the middle pointer, many fail to see that the actual answer is the left pointer's final value.

Issue in making a String Algorithm

Given a string made up of 'a' and 'b' only,the operation that is allowed is to remove a substring of "abb" if present from the string. My question is after applying this operation any no of times can i make the string empty. I need a O(n) algorithm.
Example ,
abbabb-->yes
aabbbb->yes since aabbbb->abb->empty
aaabbb->no since aaabbb->aab
All that i can think upto now is an O(n^2) algorithm in which i sucessively find the position of the substring using substr() or find() and then remove it until string not empty or not found a "abb" in it.
Here is an example of what I suggested in the comment:
for i = 0 to word.length-1
if word[i] == 'b'
if stack.empty() //no corresponding a
return false
if stack.top() == 'a' //first b after an a
stack.push('b')
else //second b after an a
stack.pop() //pop last two letters
stack.pop()
else
stack.push('a')
return stack.empty()
There might be some boundary conditions that needs to be checked, and of course at any point pop() fails you need to return false. Seems to be working for the possible inputs that occurs to me.
The point that needs to be mathematically proved, I think, is the part where I commented "second b after an a". With the assumption that stack was empty at the beginning, if I did not miss anything that point looks correct.
It is not necessary to store anything but the count of unused pairs of b's at the end of the string, as you read it Right to Left. (And it's solved reading input only once, so O(n) time O(1) space) This is very reminiscent of finding a discrete finite automata for a regular language. If you see two b's, increase count. If you see a single b, add half a pair (update a boolean variable and possibly increment count). If you see an a and have no pair of b's, fail, else count--. If you reach the end of the string and there were no extra b's, the string was valid.
Make use of two counters to avoid using stack. Here is the c++ implementaion hope it works.
bool canBeDone(string s)
{
int aCount = 0;
int bCount = 0;
for(int i=0;i<s.length();++i)
{
if(s[i] == 'a')
{
aCount++;
continue;
}
if(s[i] == 'b' && aCount == 0)
return false;
else
{
bCount += 1;
if(bCount == 2)
{
bCount = 0;
aCount--;
}
}
}
if(!aCount && !bCount)return true;
return false;
}
Very simple and straightforward implementation in Erlang O(n) space and time (unfortunately even clwhisk's algorithm needs O(n) space in Erlang because of lists:reverse/1):
-module(abb).
-export([check/1, clwhisk/1, test/0]).
check(L) when is_list(L) ->
check(L, []).
check(L, "bba" ++ T) -> check(L, T);
check([H|T], S) -> check(T, [H|S]);
check([], S) -> S =:= [].
clwhisk(L) when is_list(L) ->
clwhisk(lists:reverse(L), 0).
clwhisk([$b|T], C) -> clwhisk(T, C+1);
clwhisk([$a|T], C) -> C >= 2 andalso clwhisk(T, C-2);
clwhisk(L, C) -> L =:= [] andalso C =:= 0.
test() ->
true = abb:check("abbabb"),
true = abb:check("aabbbb"),
false = abb:check("aaabbb"),
true = abb:check("ababbb"),
true = abb:clwhisk("abbabb"),
true = abb:clwhisk("aabbbb"),
false = abb:clwhisk("aaabbb"),
true = abb:clwhisk("ababbb"),
ok.
And there is C implementation of clwhisk's algorithm as filter:
#include <stdlib.h>
#include <stdio.h>
static inline const char *last(const char* s){
for(;*s && *s!='\n';s++);
return s-1;
}
static int check(const char* s){
int count=0;
const char *ptr = last(s);
for(; ptr >= s; ptr--)
if(*ptr == 'b') {
count++;
}
else if(*ptr == 'a') {
count -= 2;
if(count < 0)
return 0;
}
else return 0;
return count == 0;
}
int main(void) {
char *line = NULL;
size_t len = 0;
while( getline(&line, &len, stdin) != -1 )
if(*line && *line != '\n' && check(line))
fputs(line, stdout);
return EXIT_SUCCESS;
}

How to find validity of a string of parentheses, curly brackets and square brackets?

I recently came in contact with this interesting problem. You are given a string containing just the characters '(', ')', '{', '}', '[' and ']', for example, "[{()}]", you need to write a function which will check validity of such an input string, function may be like this:
bool isValid(char* s);
these brackets have to close in the correct order, for example "()" and "()[]{}" are all valid but "(]", "([)]" and "{{{{" are not!
I came out with following O(n) time and O(n) space complexity solution, which works fine:
Maintain a stack of characters.
Whenever you find opening braces '(', '{' OR '[' push it on the stack.
Whenever you find closing braces ')', '}' OR ']' , check if top of stack is corresponding opening bracket, if yes, then pop the stack, else break the loop and return false.
Repeat steps 2 - 3 until end of the string.
This works, but can we optimize it for space, may be constant extra space, I understand that time complexity cannot be less than O(n) as we have to look at every character.
So my question is can we solve this problem in O(1) space?
With reference to the excellent answer from Matthieu M., here is an implementation in C# that seems to work beautifully.
/// <summary>
/// Checks to see if brackets are well formed.
/// Passes "Valid parentheses" challenge on www.codeeval.com,
/// which is a programming challenge site much like www.projecteuler.net.
/// </summary>
/// <param name="input">Input string, consisting of nothing but various types of brackets.</param>
/// <returns>True if brackets are well formed, false if not.</returns>
static bool IsWellFormedBrackets(string input)
{
string previous = "";
while (input.Length != previous.Length)
{
previous = input;
input = input
.Replace("()", String.Empty)
.Replace("[]", String.Empty)
.Replace("{}", String.Empty);
}
return (input.Length == 0);
}
Essentially, all it does is remove pairs of brackets until there are none left to remove; if there is anything left the brackets are not well formed.
Examples of well formed brackets:
()[]
{()[]}
Example of malformed brackets:
([)]
{()[}]
Actually, there's a deterministic log-space algorithm due to Ritchie and Springsteel: http://dx.doi.org/10.1016/S0019-9958(72)90205-7 (paywalled, sorry not online). Since we need log bits to index the string, this is space-optimal.
If you're willing to accept one-sided error, then there's an algorithm that uses n polylog(n) time and polylog(n) space: http://www.eccc.uni-trier.de/report/2009/119/
If the input is read-only, I don't think we can do O(1) space. It is a well known fact that any O(1) space decidable language is regular (i.e writeable as a regular expression). The set of strings you have is not a regular language.
Of course, this is about a Turing Machine. I would expect it to be true for fixed word RAM machines too.
Edit: Although simple, this algorithm is actually O(n^2) in terms of character comparisons. To demonstrate it, one can simply generate a string as '(' * n + ')' * n.
I have a simple, though perhaps erroneous idea, that I will submit to your criticisms.
It's a destructive algorithm, which means that if you ever need the string it would not help (since you would need to copy it down).
Otherwise, the algorithm work with a simple index within the current string.
The idea is to remove pairs one after the others:
([{}()])
([()])
([])
()
empty -> OK
It is based on the simple fact that if we have matching pairs, then at least one is of the form () without any pair character in between.
Algorithm:
i := 0
Find a matching pair from i. If none is found, then the string is not valid. If one is found, let i be the index of the first character.
Remove [i:i+1] from the string
If i is at the end of the string, and the string is not empty, it's a failure.
If [i-1:i] is a matching pair, i := i-1 and back to 3.
Else, back to 1.
The algorithm is O(n) in complexity because:
each iteration of the loop removes 2 characters from the string
the step 2., which is linear, is naturally bound (i cannot grow indefinitely)
And it's O(1) in space because only the index is required.
Of course, if you can't afford to destroy the string, then you'll have to copy it, and that's O(n) in space so no real benefit there!
Unless, of course, I am deeply mistaken somewhere... and perhaps someone could use the original idea (there is a pair somewhere) to better effect.
I doubt you'll find a better solution, since even if you use internal functions to regexp or count occurrences, they still have a O(...) cost. I'd say your solution is the best :)
To optimize for space you could do some run-length encoding on your stack, but I doubt it would gain you very much, except in cases like {{{{{{{{{{}}}}}}}}}}.
http://www.sureinterview.com/shwqst/112007
It is natural to solve this problem with a stack.
If only '(' and ')' are used, the stack is not necessary. We just need to maintain a counter for the unmatched left '('. The expression is valid if the counter is always non-negative during the match and is zero at the end.
In general case, although the stack is still necessary, the depth of the stack can be reduced by using a counter for unmatched braces.
This is an working java code where I filter out the brackets from the string expression and then check the well formedness by replacing wellformed braces by nulls
Sample input = (a+{b+c}-[d-e])+[f]-[g] FilterBrackets will output = ({}[])[][] Then I check for wellformedness.
Comments welcome.
public class ParanString {
public static void main(String[] args) {
String s = FilterBrackets("(a+{b+c}-[d-e])[][]");
while ((s.length()!=0) && (s.contains("[]")||s.contains("()")||s.contains("{}")))
{
//System.out.println(s.length());
//System.out.println(s);
s = s.replace("[]", "");
s = s.replace("()", "");
s = s.replace("{}", "");
}
if(s.length()==0)
{
System.out.println("Well Formed");
}
else
{
System.out.println("Not Well Formed");
}
}
public static String FilterBrackets(String str)
{
int len=str.length();
char arr[] = str.toCharArray();
String filter = "";
for (int i = 0; i < len; i++)
{
if ((arr[i]=='(') || (arr[i]==')') || (arr[i]=='[') || (arr[i]==']') || (arr[i]=='{') || (arr[i]=='}'))
{
filter=filter+arr[i];
}
}
return filter;
}
}
The following modification of Sbusidan's answer is O(n2) time complex but O(log n) space simple.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
char opposite(char bracket) {
switch(bracket) {
case '[':
return ']';
case '(':
return ')';
}
}
bool is_balanced(int length, char *s) {
int depth, target_depth, index;
char target_bracket;
if(length % 2 != 0) {
return false;
}
for(target_depth = length/2; target_depth > 0; target_depth--) {
depth=0;
for(index = 0; index < length; index++) {
switch(s[index]) {
case '(':
case '[':
depth++;
if(depth == target_depth) target_bracket = opposite(s[index]);
break;
case ')':
case ']':
if(depth == 0) return false;
if(depth == target_depth && s[index] != target_bracket) return false;
depth--;
break;
}
}
}
}
void main(char* argv[]) {
char input[] = "([)[(])]";
char *balanced = is_balanced(strlen(input), input) ? "balanced" : "imbalanced";
printf("%s is %s.\n", input, balanced);
}
If you can overwrite the input string (not reasonable in the use cases I envision, but what the heck...) you can do it in constant space, though I believe the time requirement goes up to O(n2).
Like this:
string s = input
char c = null
int i=0
do
if s[i] isAOpenChar()
c = s[i]
else if
c = isACloseChar()
if closeMatchesOpen(s[i],c)
erase s[i]
while s[--i] != c ;
erase s[i]
c == null
i = 0; // Not optimal! It would be better to back up until you find an opening character
else
return fail
end if
while (s[++i] != EOS)
if c==null
return pass
else
return fail
The essence of this is to use the early part of the input as the stack.
I know I'm a little late to this party; it's also my very first post on StackOverflow.
But when I looked through the answers, I thought I might be able to come up with a better solution.
So my solution is to use a few pointers.
It doesn't even have to use any RAM storage, as registers can be used for this.
I have not tested the code; it's written it on the fly.
You'll need to fix my typos, and debug it, but I believe you'll get the idea.
Memory usage: Only the CPU registers in most cases.
CPU usage: It depends, but approximately twice the time it takes to read the string.
Modifies memory: No.
b: string beginning, e: string end.
l: left position, r: right position.
c: char, m: match char
if r reaches the end of the string, we have a success.
l goes backwards from r towards b.
Whenever r meets a new start kind, set l = r.
when l reaches b, we're done with the block; jump to beginning of next block.
const char *chk(const char *b, int len) /* option 2: remove int len */
{
char c, m;
const char *l, *r;
e = &b[len]; /* option 2: remove. */
l = b;
r = b;
while(r < e) /* option 2: change to while(1) */
{
c = *r++;
/* option 2: if(0 == c) break; */
if('(' == c || '{' == c || '[' == c)
{
l = r;
}
else if(')' == c || ']' == c || '}' == c)
{
/* find 'previous' starting brace */
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
/* now check if we have the correct one: */
if(((m & 1) + 1 + m) != c) /* cryptic: convert starting kind to ending kind and match with c */
{
return(r - 1); /* point to error */
}
if(l <= b) /* did we reach the beginning of this block ? */
{
b = r; /* set new beginning to 'head' */
l = b; /* obsolete: make left is in range. */
}
}
}
m = 0;
while(l > b && '(' != m && '[' != m && '{' != m)
{
m = *--l;
}
return(m ? l : NULL); /* NULL-pointer for OK */
}
After thinking about this approach for a while, I realized that it will not work as it is right now.
The problem will be that if you have "[()()]", it'll fail when reaching the ']'.
But instead of deleting the proposed solution, I'll leave it here, as it's actually not impossible to make it work, it does require some modification, though.
/**
*
* #author madhusudan
*/
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Main().validateBraces("()()()()(((((())))))()()()()()()()()");
// TODO code application logic here
}
/**
* #Use this method to validate braces
*/
public void validateBraces(String teststr)
{
StringBuffer teststr1=new StringBuffer(teststr);
int ind=-1;
for(int i=0;i<teststr1.length();)
{
if(teststr1.length()<1)
break;
char ch=teststr1.charAt(0);
if(isClose(ch))
break;
else if(isOpen(ch))
{
ind=teststr1.indexOf(")", i);
if(ind==-1)
break;
teststr1=teststr1.deleteCharAt(ind).deleteCharAt(i);
}
else if(isClose(ch))
{
teststr1=deleteOpenBraces(teststr1,0,i);
}
}
if(teststr1.length()>0)
{
System.out.println("Invalid");
}else
{
System.out.println("Valid");
}
}
public boolean isOpen(char ch)
{
if("(".equals(Character.toString(ch)))
{
return true;
}else
return false;
}
public boolean isClose(char ch)
{
if(")".equals(Character.toString(ch)))
{
return true;
}else
return false;
}
public StringBuffer deleteOpenBraces(StringBuffer str,int start,int end)
{
char ar[]=str.toString().toCharArray();
for(int i=start;i<end;i++)
{
if("(".equals(ar[i]))
str=str.deleteCharAt(i).deleteCharAt(end);
break;
}
return str;
}
}
Instead of putting braces into the stack, you could use two pointers to check the characters of the string. one start from the beginning of the string and the other start from end of the string. something like
bool isValid(char* s) {
start = find_first_brace(s);
end = find_last_brace(s);
while (start <= end) {
if (!IsPair(start,end)) return false;
// move the pointer forward until reach a brace
start = find_next_brace(start);
// move the pointer backward until reach a brace
end = find_prev_brace(end);
}
return true;
}
Note that there are some corner case not handled.
I think that you can implement an O(n) algorithm. Simply you have to initialise an counter variable for each type: curly, square and normal brackets. After than you should iterate the string and should increase the coresponding counter if the bracket is opened, otherwise to decrease it. If the counter is negative return false. AfterI think that you can implement an O(n) algorithm. Simply you have to initialise an counter variable for each type: curly, square and normal brackets. After than you should iterate the string and should increase the coresponding counter if the bracket is opened, otherwise to decrease it. If the counter is negative return false. After you count all brackets, you should check if all counters are zero. In that case, the string is valid and you should return true.
You could provide the value and check if its a valid one, it would print YES otherwise it would print NO
static void Main(string[] args)
{
string value = "(((([{[(}]}]))))";
List<string> jj = new List<string>();
if (!(value.Length % 2 == 0))
{
Console.WriteLine("NO");
}
else
{
bool isValid = true;
List<string> items = new List<string>();
for (int i = 0; i < value.Length; i++)
{
string item = value.Substring(i, 1);
if (item == "(" || item == "{" || item == "[")
{
items.Add(item);
}
else
{
string openItem = items[items.Count - 1];
if (((item == ")" && openItem == "(")) || (item == "}" && openItem == "{") || (item == "]" && openItem == "["))
{
items.RemoveAt(items.Count - 1);
}
else
{
isValid = false;
break;
}
}
}
if (isValid)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("NO");
}
}
Console.ReadKey();
}
var verify = function(text)
{
var symbolsArray = ['[]', '()', '<>'];
var symbolReg = function(n)
{
var reg = [];
for (var i = 0; i < symbolsArray.length; i++) {
reg.push('\\' + symbolsArray[i][n]);
}
return new RegExp('(' + reg.join('|') + ')','g');
};
// openReg matches '(', '[' and '<' and return true or false
var openReg = symbolReg(0);
// closeReg matches ')', ']' and '>' and return true or false
var closeReg = symbolReg(1);
// nestTest matches openSymbol+anyChar+closeSymbol
// and returns an obj with the match str and it's start index
var nestTest = function(symbols, text)
{
var open = symbols[0]
, close = symbols[1]
, reg = new RegExp('(\\' + open + ')([\\s\\S])*(\\' + close + ')','g')
, test = reg.exec(text);
if (test) return {
start: test.index,
str: test[0]
};
else return false;
};
var recursiveCheck = function(text)
{
var i, nestTests = [], test, symbols;
// nestTest with each symbol
for (i = 0; i < symbolsArray.length; i++)
{
symbols = symbolsArray[i];
test = nestTest(symbols, text);
if (test) nestTests.push(test);
}
// sort tests by start index
nestTests.sort(function(a, b)
{
return a.start - b.start;
});
if (nestTests.length)
{
// build nest data: calculate match end index
for (i = 0; i < nestTests.length; i++)
{
test = nestTests[i];
var end = test.start + ( (test.str) ? test.str.length : 0 );
nestTests[i].end = end;
var last = (nestTests[i + 1]) ? nestTests[i + 1].index : text.length;
nestTests[i].pos = text.substring(end, last);
}
for (i = 0; i < nestTests.length; i++)
{
test = nestTests[i];
// recursive checks what's after the nest
if (test.pos.length && !recursiveCheck(test.pos)) return false;
// recursive checks what's in the nest
if (test.str.length) {
test.str = test.str.substring(1, test.str.length - 1);
return recursiveCheck(test.str);
} else return true;
}
} else {
// if no nests then check for orphan symbols
var closeTest = closeReg.test(text);
var openTest = openReg.test(text);
return !(closeTest || openTest);
}
};
return recursiveCheck(text);
};
Using c# OOPS programming... Small and simple solution
Console.WriteLine("Enter the string");
string str = Console.ReadLine();
int length = str.Length;
if (length % 2 == 0)
{
while (length > 0 && str.Length > 0)
{
for (int i = 0; i < str.Length; i++)
{
if (i + 1 < str.Length)
{
switch (str[i])
{
case '{':
if (str[i + 1] == '}')
str = str.Remove(i, 2);
break;
case '(':
if (str[i + 1] == ')')
str = str.Remove(i, 2);
break;
case '[':
if (str[i + 1] == ']')
str = str.Remove(i, 2);
break;
}
}
}
length--;
}
if(str.Length > 0)
Console.WriteLine("Invalid input");
else
Console.WriteLine("Valid input");
}
else
Console.WriteLine("Invalid input");
Console.ReadKey();
This is my solution to the problem.
O(n) is the complexity of time without complexity of space.
Code in C.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool checkBraket(char *s)
{
int curly = 0, rounded = 0, squre = 0;
int i = 0;
char ch = s[0];
while (ch != '\0')
{
if (ch == '{') curly++;
if (ch == '}') {
if (curly == 0) {
return false;
} else {
curly--; }
}
if (ch == '[') squre++;
if (ch == ']') {
if (squre == 0) {
return false;
} else {
squre--;
}
}
if (ch == '(') rounded++;
if (ch == ')') {
if (rounded == 0) {
return false;
} else {
rounded--;
}
}
i++;
ch = s[i];
}
if (curly == 0 && rounded == 0 && squre == 0){
return true;
}
else {
return false;
}
}
void main()
{
char mystring[] = "{{{{{[(())}}]}}}";
int answer = checkBraket(mystring);
printf("my answer is %d\n", answer);
return;
}

Resources