11

Problem description from codility :

A string S consisting of N characters is considered to be properly nested if any of the following conditions is true:

S is empty; S has the form "(U)" or "[U]" or "{U}" where U is a properly nested string; S has the form "VW" where V and W are properly nested strings. For example, the string "{[()()]}" is properly nested but "([)()]" is not.

Write a function:

class Solution { public int solution(String S); }

that, given a string S consisting of N characters, returns 1 if S is properly nested and 0 otherwise.

For example, given S = "{[()()]}", the function should return 1 and given S = "([)()]", the function should return 0, as explained above.

Assume that:

N is an integer within the range [0..200,000]; string S consists only of the following characters: "(", "{", "[", "]", "}" and/or ")". Complexity:

expected worst-case time complexity is O(N); expected worst-case space complexity is O(N) (not counting the storage required for input arguments).

I get 87% I cant seem to figure out the problem.

enter image description here

Here is my code :

   // you can also use imports, for example:
// import java.util.*;
import java.util.Stack;
// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
   public int solution(String s) {

        if (s.length() % 2 != 0) {
            return 0;
        }

        Character openingBrace = new Character('{');
        Character openingBracket = new Character('[');
        Character openingParen = new Character('(');
        Stack<Character> openingStack = new Stack<Character>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == openingBrace || c == openingBracket || c == openingParen) {
                openingStack.push(c);
            } else  {
                if (i == s.length()-1 && openingStack.size() != 1) {
                    return 0;
                }
                if (openingStack.isEmpty()) {
                    return 0;
                }
                Character openingCharacter = openingStack.pop();
                switch (c) {
                case '}':
                    if (!openingCharacter.equals(openingBrace)) {
                        return 0;
                    }
                    break;
                case ']':
                    if (!openingCharacter.equals(openingBracket)) {
                        return 0;
                    }
                    break;
                case ')':
                    if (!openingCharacter.equals(openingParen)) {
                        return 0;
                    }
                    break;

                default:
                    break;
                }
            } 
        }

        return 1;

    }
}
klind
  • 855
  • 2
  • 21
  • 33
  • Do you have an example of the input that your code is failing to properly validate? – Morgen Mar 09 '15 at 21:01
  • I'm getting horrible interview flashbacks from this question. – Holloway Mar 09 '15 at 21:15
  • I do not have the input, codiliy does not provide that. I dont know what they mean by "negative_match invalid structures" – klind Mar 09 '15 at 21:19
  • You can do the test here https://codility.com/c/intro/demo7MQR6Q-232 – klind Mar 09 '15 at 21:19
  • 2
    "negative_match" is `))((` – Holloway Mar 09 '15 at 21:27
  • I couldn't see what was wrong here so I wrote a new solution. If it helps [this](https://gist.github.com/anonymous/153ada279464ebab9325) works. – Holloway Mar 09 '15 at 22:07
  • default: break; Maybe you should return 0 here in case some illegal character comes – алекс кей Feb 10 '17 at 09:53
  • In my opinion, the main problem is time complexity here guys, you should detect that right character comes to stack before left so it does not matter what is after these sequence (sequence like: ')(+whatever characters like []()()(){}' – Marek Staňa Oct 19 '18 at 19:58

33 Answers33

9

Simple java solution, 100/100

public int solution(String S) {
        Deque<Character> stack = new ArrayDeque<Character>();

        for(int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);

            switch (c) {
                case ')':
                    if (stack.isEmpty() || stack.pop() != '(')
                        return 0;
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[')
                        return 0;
                    break;
                case '}':
                    if(stack.isEmpty() || stack.pop() != '{')
                        return 0;
                    break;
                default:
                    stack.push(c);
                    break;
            }
        }

        return stack.isEmpty() ? 1 : 0;
    }
Elaina
  • 184
  • 2
  • 8
5

Your first condition in the closing brackets block checks whether your stack has the size != 1. I assume this is meant to check that you don't have any leftover opening brackets, which is a good idea. However, you'll miss this entire check if your last char isn't a closing bracket/paren/..

This for example would fail for an input like (((.

A simple fix would be replacing this condition with a check after the loop ends that the stack is indeed empty.

Leeor
  • 19,260
  • 5
  • 56
  • 87
5

Short and clean Python solution to this problem. 100% in Codility

def solution(S):

    matches, stack = dict(['()', '[]', '{}']), []

    for i in S:
        if i in matches.values():
            if stack and matches[stack[-1]] == i:
                stack.pop()
            else:
                return 0
        else:
            stack.append(i)

    return int(not stack)
Francisco Sandi
  • 993
  • 10
  • 10
2

100% simple JavaScript solution

function solution(S) {
  S = S.split("");
  var stack = [];
  for (var i = 0; i < S.length; i++) {
    var c = S[i];
    if (c == '{' || c == '(' || c == '[')
      stack.push(c);
    else if (c == '}' || c == ')' || c == ']') {
      var t = stack.pop() + c;
      if (t != "{}" && t != "()" && t != "[]")
        return 0;
    }
    else 
      return 0;
  }

  if (stack.length > 0)
    return 0;

  return 1;
}
Jung Oh
  • 29
  • 1
2

Passed codility test 100/100 in java.

public static int solution(String S){
    Stack<Character> stack = new Stack<Character>();
    if(null == S){
        return 0;
    }else if(S.isEmpty()){
        return 1;
    }
    for (Character C : S.toCharArray()) {

        switch (C) {
        case ')':
            pops(stack, '(');
            break;
        case '}':
            pops(stack, '{');
            break;
        case ']':
            pops(stack, '[');
            break;

        default:
            stack.push(C);
            break;
        }

    }
    return stack.isEmpty() ? 1 : 0;
}

private static void pops(Stack<Character> s, Character  C){

        while(!s.isEmpty() && s.peek() != C){
            s.pop();
        }
        if(!s.isEmpty()){
            s.pop();
        }else{
            s.push(C);
        }
}
Vivek
  • 11,938
  • 19
  • 92
  • 127
2

This is my C# simple solution which got 100% for Correctness and 100% Performance. Time Complexity is O(N). https://codility.com/demo/results/trainingRVS3SF-DC6/

using System;
using System.Collections.Generic;

class Solution {

    public int solution(string S) {

        // Return 1 if string size is 0 
        if(S.Length==0) return 1;

        Stack<char> brackets = new Stack<char>();

        foreach(char c in S){
            if(c=='['||c=='{'||c=='('){
                brackets.Push(c);
            }
            else{
                // return 0 if no opening brackets found and 
                // first bracket is a closing bracket
                if(brackets.Count==0) return 0;

                if(c==')'){
                    if(brackets.Peek()=='(') brackets.Pop();
                    else return 0;
                }

                if(c=='}'){
                    if(brackets.Peek()=='{') brackets.Pop();
                    else return 0;
                }

                if(c==']'){
                    if(brackets.Peek()=='[') brackets.Pop();
                    else return 0;
                }
            }
        }

        if(brackets.Count==0) return 1;

        return 0;
    }
}
  • I make same solution but with php and the performance is different. I create the stack myself ih php since there is no built in stack https://app.codility.com/demo/results/trainingFR4VME-Q88/ Can u recommend any improvement plz – palAlaa Jan 29 '18 at 09:34
2

My 100% solution in C#.

using System;
using System.Collections.Generic;
using System.Linq;

class Solution {
    private Dictionary<char,char> closing = new Dictionary<char,char>{{'}','{'},{')','('},{']','['}};
    public int solution(string S) {
        var stack = new Stack<char>();
        foreach(var c in S)
        {
            if(!closing.Keys.Contains(c))
                stack.Push(c);
            else if(!stack.Any() || closing[c] != stack.Pop() )
                return 0;
        }
        return !stack.Any() ? 1 : 0;
    }
}
1

I got 100% with the following solution in java. The time complexity is O(N)

 class Solution {
  public int solution(String S) {        
    char[] charArray=S.toCharArray();
    //This array works as stack
    char[] stack=new char[charArray.length];        
    //currently stack is empty
    int stackSize=0;
    for(int i=0;i<charArray.length;i++){
   //Check start characters and add it to stack
        if(charArray[i]=='{' ||charArray[i]=='(' || charArray[i]=='['){                
            stack[stackSize++]=charArray[i];                                
        }else{
            //This section checks for end character. 
           //End characters with stack being empty confirms not nested
            if(stackSize==0){
             result=0;
             break;
            }
            //Pop stack
            char ch=stack[--stackSize];   
            //check
            if((charArray[i]=='}' && ch=='{') || (charArray[i]==']' && ch=='[') ||(charArray[i]==')' && ch=='(')){                     
                continue;
            }else{
               //if pop character not matching, confirms non nesting 
                result=0;
                break;
            }                   
        }
    }
    //if stack is not empty indicates non nested, otherwise result 
    return stackSize==0?result:0;
}

}

krishna
  • 123
  • 1
  • 1
  • 12
1
function solution(S) {
    if (0 === S.length) {
        return 1
    }
    let stack  = []
    for (let i = 0; i < S.length; i++) {
        if ('(' === S[i] || '{' === S[i] || '[' === S[i]) {
            stack.push(S[i])
        } else {
            let couple = [stack.pop(), S[i]].join('')
            if ('()' !== couple && '{}' !== couple && '[]' !== couple) {
                return 0
            }
        } 
    }

    if (stack.length) {
        return 0
    }
    return 1
}   
CroMagnon
  • 1,218
  • 7
  • 20
  • 32
1

Couldn't find any python scripts... but here it is! Tried to keep it as simple as possible.

def solution(S):
# write your code in Python 3.6

arr = []

if len(S) < 1:
    return 1

if not isinstance(S, str):
    return 0

for i in range(0, len(S)):
    # print(S[i])
    if startSym(S[i]):
        arr.append(value(S[i]))
        # print(arr)

    elif endSym(S[i]):
        if len(arr) > 0 and value(S[i]) == arr[len(arr) - 1]:
            # print(S[i])
            # print(arr)
            del arr[len(arr) - 1]
        else:
            return 0

    else:
        return 0

if len(arr) == 0:
    return 1
else:
    return 0

def startSym(x):
if x == '{' or x == '[' or x == '(':
    return True
else:
    return False

def endSym(x):
if x == '}' or x == ']' or x == ')':
    return True
else:
    return False

def value(x):
if x == '{' or x == '}':
    return 1
if x == '[' or x == ']':
    return 2
if x == '(' or x == ')':
    return 3
1

Swift 5 (100%)

public func solution(_ S : inout String) -> Int {
var stack: [Character] = []
let pairFor: [Character: Character] = ["(":")",
                                       "{":"}",
                                       "[":"]"]
let opening: Set<Character> = ["(","{","["]
let closing: Set<Character> = [")","}","]"]

for char in S {
    if opening.contains(char) {
        stack.append(char)

    } else if closing.contains(char) {
        guard stack.isEmpty == false else {
            return 0
        }
        let bracket = stack.removeLast()

        if pairFor[bracket] != char {
            return 0
        }
    }
}

return stack.isEmpty ? 1 : 0

}

1
class Solution {
public int solution(String S) {
    // write your code in Java SE 8
    Stack<Character> myStack = new Stack<Character>();
    for(Character singleChar : S.toCharArray()){
        if((singleChar.equals('(')) || (singleChar.equals('{')) || (singleChar.equals('['))){
            myStack.push(singleChar);
        }
        else{
            if(myStack.size() == 0){
                System.out.println("Stack size");
                return 0;
            }
            if(singleChar.equals(')')){
                if(myStack.peek().equals('('))
                    myStack.pop();
                else
                    return 0;
            }
             if(singleChar.equals('}')){
                if(myStack.peek().equals('{'))
                    myStack.pop();
                else
                    return 0;
            }
             if(singleChar.equals(']')){
                if(myStack.peek().equals('['))
                    myStack.pop();
                else
                    return 0;
            }
        }
    }
    if(myStack.size()==0)
    return 1;
    else
    return 0;
}

}

1

My 100% JavaScript solution with O(N) time complexity:

function solution(S) {

    const openingTags = {
        '[': ']',
        '{': '}',
        '(': ')',
    };

    const stack = [];

    for (const char of S) {
        // if char is not an opening tag, it is a closing tag
        if (openingTags.hasOwnProperty(char)) {
            stack.push(char);
        } else if (openingTags[stack.pop()] !== char) {
            return 0;
        }

    }

    return Number(stack.length < 1);

}
noviewpoint
  • 574
  • 1
  • 10
  • 20
0

Your best bet with these sort of errors is to sit down and writes some unit tests (JUnit is a good framework) to verify your understanding of how the algorithm works.

In this case, as Trengot has figured out that the "negative_match" input is ))((, you'll want at least these test cases:

  • ))(( : This is your base test, once this is passing you're fulfilling the requirements, and can declare at least partial victory.
  • }}{{ : Is this a general error, or only related to mishandling a particular character?
  • })({ : Is it related to the repeated character, or does it show up in mixed input as well?
  • (}{) : Is this an edge-case related to having an opening token at the start of the string, or does this behavior show up more generally?

Once you understand what it is actually doing, instead of what your brain tells you it is doing (and your brain will lie to you about this), fixing it should be fairly straightforward.

Community
  • 1
  • 1
Morgen
  • 1,010
  • 1
  • 11
  • 15
  • 1
    I submitted a solution of just `System.out.println(S);return 0;` and that was the output for that test. – Holloway Mar 09 '15 at 21:43
  • @Trengot - Very clever, the simple solution is sometimes the easiest to overlook. – Morgen Mar 09 '15 at 21:48
  • It appears they randomly generate test cases. Running it again gave `())(()`. I wonder if that was the cause of OP's problem. – Holloway Mar 09 '15 at 22:12
0

So after Leeor suggestions here is a 100% solution

// you can also use imports, for example:
// import java.util.*;
import java.util.Stack;
// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
   public int solution(String s) {

        if (s.length() % 2 != 0) {
            return 0;
        }

        Character openingBrace = new Character('{');
        Character openingBracket = new Character('[');
        Character openingParen = new Character('(');
        Stack<Character> openingStack = new Stack<Character>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == openingBrace || c == openingBracket || c == openingParen) {
                openingStack.push(c);
            } else  {
                if (openingStack.isEmpty()) {
                    return 0;
                }
                Character openingCharacter = openingStack.pop();
                switch (c) {
                case '}':
                    if (!openingCharacter.equals(openingBrace)) {
                        return 0;
                    }
                    break;
                case ']':
                    if (!openingCharacter.equals(openingBracket)) {
                        return 0;
                    }
                    break;
                case ')':
                    if (!openingCharacter.equals(openingParen)) {
                        return 0;
                    }
                    break;

                default:
                    break;
                }
            } 
        }
        if (!openingStack.isEmpty()) {
            return 0;
        }

        return 1;

    }
}
klind
  • 855
  • 2
  • 21
  • 33
0

Code: 06:12:11 UTC, c, final, score: 100.00

int solution(char *S) {
    // write your code in C99
    int len;
    if((len=strlen(S))==0) return 1;
    char stuck[len];
    char open[]="([{";
    char close[]=")]}";
    int top=0;
    for (int i=0;i<len;i++)
        {
            if (strchr(open,S[i])!=NULL)
            {
                stuck[top]=S[i];
                top++;
            } 
            else if (strchr(close,S[i])!=NULL)
            {
              if ((top>0)&&((strchr(open,stuck[top-1])-open)==(strchr(close,S[i])-close)))
              top--;
            else
                return 0;
            }
        }
        if (top==0)
        return 1;
        return 0;
    }
David Yachnis
  • 484
  • 5
  • 14
0

Here's a Java 100/100:

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
class Solution {
public static final int BALANCED = 1;
public static final int UNBALANCED = 0;

public int solution(String S) {
    if (S.isEmpty()) return BALANCED;

    Stack<Character> stack = new Stack<>(S.length());
    NestedValidatorUtil util = new NestedValidatorUtil();

    for (char c: S.toCharArray()) {
        if (stack.isEmpty()){
            if (util.isOpener(c)) {
                stack.push(c);
            } else {
                return UNBALANCED;
            }
        } else {
            if(util.isOpener(c)) {
                stack.push(c);
            } else if(util.getOpenerForGivenCloser(c) == stack.peek()){
                stack.pop();
            } else {
                return UNBALANCED;
            }
        }
    }

    return stack.isEmpty() ? BALANCED : UNBALANCED;
}

public static class NestedValidatorUtil {
    private Map<Character, Character> language = new HashMap<Character, Character>(){{
        put(')','(');
        put(']','[');
        put('}','{');
        }};

    public boolean isOpener(Character c) {
        return language.values().contains(c);
    }

    public Character getOpenerForGivenCloser(Character closer) {
        return language.get(closer);
    }
}

public static class Stack<T> {
      public List<T> stack;

      public Stack(int capacity) {
          stack = new ArrayList<>(capacity);
      }

      public void push(T item) {
          stack.add(item);
      }

      public T pop() {
          T item = peek();
          stack.remove(stack.size() - 1);
          return item;
      }

      public T peek() {
          int position = stack.size();
          T item = stack.get(position - 1);
          return item;
      }

      public boolean isEmpty() {
          return stack.isEmpty();
      }
  }
}

Here's a link to the code. Hope it helps.

moxi
  • 1,390
  • 20
  • 21
0

here you have my 100% solution in java: https://codility.com/demo/results/training2C7U2E-XM3/

/**
 *  https://codility.com/demo/results/training2C7U2E-XM3/ 100%
 *  
 * Problem facts:
 * 1) A string S consisting of N characters is given
 * 2) S is properly nested if:
 *      -S is empty;
 *      -S has the form "(U)" or "[U]" or "{U}" where U is a properly nested string;
 *      -S has the form "VW" where V and W are properly nested strings.
 * 3) N is an integer within the range [0..200,000];
 * 4) string S consists only of the following characters: "(", "{", "[", "]", "}" and/or ")".
 * 5) expected worst-case time complexity is O(N);
 * 6) expected worst-case space complexity is O(N)
 * 
 * Solution:
 * The idea is to iterate over the string and push opening brackets, then each time a closing bracket appears
 * it will be matched with the last opening match stacked, if both are of the same type, then pop that char,
 * otherwise return 0.
 * If the string S is properly nested the remaining stack will be empty. 
 * 
 * There are three cases to analize:
 * 1) The stack is empty, push the first char.
 * 2) The stack is not empty, peek the last char and it is the opening bracket of current closing bracket, then
 * pop the char from the stack.
 * 3) The stack is not empty, peek the last char and it isn't the opening bracket of current closing bracket, 
 * return 0, because the string is malformed.
 * 
 * @param S
 * @return 1 if S is properly nested and 0 otherwise.
 */
public static int solution(String S) {      
    if(S.isEmpty()) return 1; // pay attention to corner case 1
    if(S.length()==1) return 0; // and 2

    Stack<Character> stack = new Stack<>();     

    for(int i=0; i<S.length(); i++) {
        char current = S.charAt(i);
        switch (current) {
            case '}':
                if (!stack.isEmpty() && stack.peek() == '{') {
                    stack.pop();
                } 
                else return 0;
                break;
            case ']':
                if (!stack.isEmpty() && stack.peek() == '[') {
                    stack.pop();
                } 
                else return 0;
                break;
            case ')':
                if (!stack.isEmpty() && stack.peek() == '(') {
                    stack.pop();
                } 
                else return 0;
                break;
            default:
                stack.push(current);
                break;
        }   
    }
    return stack.size()==0 ? 1 : 0;
}
0

@Moxi and @Caesar Avgvstvs 's answers inspired mine.

But I believe mine is shorter without missing anything. My solution passed 100% in codility . I used a Map to avoid repetition. Here is my solution in Java.

import java.util.*;

public static int solution(String S) {
    if (S.isEmpty()) return 1;
    if (S.length() % 2 == 1) return 0;  // the length cannot be an odd number.
    // in time complexity this decreases from O(n) to O(1).

    // this Map avoid the ugly "switch case"
    Map<Character, Character> map = new HashMap<Character, Character>();
    map.put('}', '{');
    map.put(')', '(');
    map.put(']', '[');

    Stack<Character> stack = new Stack<Character>();
    for (Character c : S.toCharArray()) {
        if (map.containsKey(c)) {
            if (!stack.isEmpty() && map.get(c) == stack.peek()) {
                stack.pop();
            } else {
                return 0;
            }
        } else {
            stack.push(c);
        }
    }
    return stack.isEmpty() ? 1 : 0;
}
Raymond Chenon
  • 11,482
  • 15
  • 77
  • 110
0

100% Java

public int solution(String S) {
    Stack<Character> stack = new Stack<>();    
    for(int i=0; i<S.length(); i++) {
        char c = S.charAt(i);
        if (c == '[' || c == '{' || c == '(' || c == 'V') {
            stack.push(c);
        } else if (c == ']' || c == '}' || c == ')' || c == 'W') {
            if (checkBracket(stack, c)) {
                stack.pop();
            } else {
                return 0;
            }  
        } else {
            return 0;
        }
    }   
    if (stack.empty()) {
        return 1;
    }
    return 0;  
}

private boolean checkBracket(Stack<Character> stack, char bracket) {
    if (stack.empty()) return false;
    char lastStackBracket = stack.peek();
    if (lastStackBracket == '{' && bracket == '}') {
        return true;
    } else if (lastStackBracket == '[' && bracket == ']') {
        return true;
    } else if (lastStackBracket == '(' && bracket == ')') {
        return true;
    } else if (lastStackBracket == 'V' && bracket == 'W') {
        return true;
    }
    return false;
}

of course you need to import java.util:

import java.util.*;
Dario Sagud
  • 81
  • 1
  • 8
0

My solution in Swift. Should work correctly

public func Brackets(_ S : inout String) -> Int {

    var Stack = [Character]()

    let matching : [Character:Character] = ["(":")", "[":"]", "{":"}"]

    for s in S {
        let char = S.removeFirst()
        if "({[".contains(char) {
            print(char)
            Stack.append(char)
        }
        if( "]})".contains(char)) {
            print(char)
            let bracket = Stack.removeLast()
            if matching[bracket] != char {
                return 0
            }
        }
    }

    return 1
}

var S1 = "{[()()]}"
var S2 = "([)()]"
print("Brackets: ", Brackets(&S1))
print("Brackets: ", Brackets(&S2))
Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143
0

I know it doesn't directly related to your issue.

However I have a valid solution with run time complexity of O(N) and with space complexity of O(1). This solution got 100/100 at codility.

written in c++:

int solution(string  S) {
int N = S.size();
if(N == 0) return 1;//empty string is properly nested
if(S[0] == ')' || S[0] == ']' || S[0] == '}' ) return 0;// a properly nested string cannot beging with those chars
if(S[N-1] == '(' || S[N-1] == '[' || S[N-1] == '{' ) return 0; // cannot end with those chars
int paren_open = 0;
int brac_open = 0;
int curl_open = 0;
for(int i =0 ; i < N;++i){
   if(S[i] == ')' && (paren_open == 0 || S[i-1] == '[' || S[i-1] == '{')) return 0; //expected opening but got closing
   if(S[i] == ']' && (brac_open == 0 || S[i-1] == '(' || S[i-1] == '{')) return 0; //same here
   if(S[i] == '}' && (curl_open == 0 || S[i-1] == '[' || S[i-1] == '(')) return 0; //same here
   if(S[i] == '(') paren_open++;
   else if(S[i] == ')') paren_open--;
   else if(S[i] == '[') brac_open++;
   else if(S[i] == ']') brac_open--;
   else if(S[i] == '{') curl_open++;
   else if(S[i] == '}') curl_open--;
}
if(paren_open == 0 && brac_open == 0 && curl_open ==0)
   return 1;
return 0;  }
  • 1
    I think this fails for '[((())])'. Possibly Codility doesn't properly check nesting. This answer - https://stackoverflow.com/a/45858026/2734863 - suggests an O(N^2) time algorithm is the only way to do this question in O(1) space if nesting is a concern. – Frikster Apr 03 '19 at 20:05
0

Ruby 100%

def solution(s)
  s.split('').inject([]) do |stack, el|
    next stack.push(el) if ['[', '{', '('].include?(el)
    current = stack.pop
    next stack if (current == '{' && el == '}') ||
                  (current == '(' && el == ')') ||
                  (current == '[' && el == ']')
    return 0
  end.empty? ? 1 : 0
end
Mike Belyakov
  • 1,355
  • 1
  • 13
  • 24
0

Here is the solution in python with 100 % at Codility

I added little explanation and steps hope this helps any one...

Idea Idea is to use stack concept Used array [] as stack Keep adding item in stack until open brackets found, Keep popping up item if closing bracket found. On each pop of item check popped item it should match with the opposite bracket as explained in example else not balanced.

Operation

4 push 4 pop
{[()()]}
push {
push [
push (
    pop )
push (
    pop )
    pop ]
    pop }
gets empty

2 push 1 pop
([)()]
(
[
    ) - not matching with [ so not balanced

Code-

def solution(S):
stack = []
for bracket in S:
    # open bracket found push in to stack, used array as stack append item at top
    if bracket == "{" or bracket == "[" or bracket == "(":
        stack.append(bracket)
    # any closing bracket found and stack is not empty remote item from stack top
    elif bracket == "}" and stack:
        pop_item = stack.pop()
        # check  popped item, if it is not similar( ie. opposite or open) as bracket then this S can not be balanced
        if pop_item != "{":
            return 0
    elif bracket == "]" and stack:
        pop_item = stack.pop()
        if pop_item != "[":
            return 0
    elif bracket == ")" and stack:
        pop_item = stack.pop()
        if pop_item != "(":
            return 0
    # at any point if neither open nor close operation can be performed, stack is not balanced
    else:
        return 0

    print(stack)

# if stack is empty stack, it is balanced ie. all push and pop operation on S is successful¬.
if not stack:
    return 1
# S is not balanced
return 0


if __name__ == '__main__':
# result = solution("{[()()]}")
result = solution("([)()]")
print("")
print("Solution " + str(result))

Run test case -

['{']
['{', '[']
['{', '[', '(']
['{', '[']
['{', '[', '(']
['{', '[']
['{']
[]

Solution 1

['(']
['(', '[']

Solution 0
0

Here is Java 100%

public int solution(String S) {
        // write your code in Java SE 8
        List open = Arrays.asList('(', '{', '[');
        List close = Arrays.asList(')', '}', ']');

        Stack<Character> stack = new Stack<Character>();
        for (int i = 0; i < S.length(); i++) {
            if (open.contains(S.charAt(i))) {
                stack.push(S.charAt(i));
            } else if (close.contains(S.charAt(i)) && !stack.isEmpty()) {
                Character top = stack.peek();
                if (open.indexOf(top) == close.indexOf(S.charAt(i))) {
                    stack.pop();
                } else {
                    return 0;
                }
            } else {
                return 0;
            }
        }
        return stack.isEmpty() ? 1 : 0;
    }
0

enter image description hereSimple and verbose solution in Python with 100% score

def solution(S):
    if len(S) == 0:
        return 1

    opening = ["(", "{", "["]
    closing = [")", "}", "]"]
    ls_my_o = []
    for s in S:
        if s in opening:
            ls_my_o.append(s)
        elif s in closing:
            if len(ls_my_o) < 1:
                return 0
            ele = ls_my_o.pop()
            if opening.index(ele) != closing.index(s):
                return 0
    if len(ls_my_o) == 0:
        return 1
    return 0
GPopat
  • 445
  • 4
  • 14
0

Javascript 100% solution

function solution(S) {
    const stack = []
    const obj = { ")": "(", "}": "{", "]": "[" }

    for (i = 0; i < S.length; i++) {
        if (S[i] === '(' || S[i] === '{' || S[i] === '[') {
            stack.push(S[i])
        } else {
            const last = stack.pop()
            if (obj[S[i]] !== last) return 0
        }
    }
    return stack.length === 0 ? 1 : 0
}
Selvio Perez
  • 100
  • 4
0

Here's a simple Python solution (100%):

# Brackets
def solution(S):
    if not S:
        return 1
    stack = []
    brackets = {"(": ")", "{": "}", "[": "]"}
    for elem in S:
        if elem in brackets:
            stack.append(elem)
        if elem in brackets.values():
            if stack:
                if elem == brackets[stack.pop()]:
                    continue
                else:
                    return 0
            else:
                return 0
    return 0 if stack else 1
SatoriChi
  • 31
  • 2
0

PHP solution with 100% accuracy

$sa = str_split($S);
if(strlen($S) == 0){
    return 1;
}
$count = count($sa);


$res =1;
$opening = ['{'=>'}','('=>')','['=>']'];
$array =['{'=>'}','}'=>'{',')'=>'(','('=>')','['=>']',']'=>'['] ;
$stack = [];
for($i =0;$i<$count;$i++){
    if(isset($opening[$sa[$i]])){
        array_push($stack,$sa[$i]);
    }else{
        if(count($stack) == 0){
            return 0;
        }
        
        $v = array_pop($stack);
        
        if($array[$sa[$i]] !== $v){
            return 0;
            
        }
    }
    
}
if (sizeof($stack) != 0) return 0;
return 1;
Mohammad
  • 11
  • 1
0

C++ (100%)

#include <stack>

int solution(string &S) {
    // write your code in C++14 (g++ 6.2.0)
    auto N = S.size();
    stack<char> ST;

    for(decltype(N) i{0}; i < N; i++) {
        if ((S[i] == '{') || (S[i] == '[') || (S[i] == '(')) {
            ST.push(S[i]);
        }
        else {
            if (ST.empty()) {
                return false;
            }
            char top = ST.top();
            ST.pop();
            if ((S[i] == ')') && (top != '(')) {
                return false;
            }
            if ((S[i] == ']') && (top != '[')) {
                return false;
            }
            if ((S[i] == '}') && (top != '{')) {
                return false;
            }
        }
    }

    return ST.empty();
}
JManirouc
  • 21
  • 3
0

I think this is a more readable Java solution with a score of 100%:

https://app.codility.com/demo/results/trainingUY545E-2EQ/

import java.util.Stack;

public class Brackets {

    public int solution(String S) {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < S.length(); i++) {
            if (!process(stack, S.charAt(i))) {
                return 0;
            }
        }

        return stack.empty() ? 1 : 0;
    }

    private boolean process(Stack<Character> stack, char ch) {
        Character opener = getOpener(ch);
        if (opener == null) {
            stack.push(ch);
        } else {
            if (stack.empty()) {
                return false;
            }

            char top = stack.peek();
            if (opener.equals(top)) {
                stack.pop();
            } else {
                return false;
            }
        }

        return true;
    }

    private Character getOpener(char ch) {
        switch (ch) {
            case ')':
                return '(';

            case '}':
                return '{';

            case ']':
                return '[';

            default:
                return null;
        }
    }
}
0

my %100 JAVA solution

class Solution {
  public int solution(String S) {
    Stack<Character> myStack = new Stack<>();
    char[] chars = S.toCharArray();
    for (int i = 0; i < chars.length; i++) {
      char coming = chars[i];
      switch(coming){
        case '(': case '{': case '[':
          myStack.push(coming);
          break;
        case ')': case '}': case ']':
          if(myStack.isEmpty())
            return 0;

          char popped = myStack.pop();
          if(!isValidPair(coming, popped))
            return 0;
      }
    }

    if(!myStack.isEmpty())
      return 0;

    return 1;
  }

  private boolean isValidPair(char c, char s) {
    return ((c == ')' && s == '(') || (c == '}' && s == '{') || (c == ']' && s == '['));
  }
}
  • You should explain in detail how your answer's solution accomplishes OP's/question's intended goal, preferably contrasting it with where OP's attempt went awry. I am a reviewer. StackOverflow requested review of this answer due to you not having very many reputation-points yet. Your answer is most appreciated & helpful. This comment is to help you take a good answer & make it excellent. – Andreas ZUERCHER Apr 27 '21 at 02:04
0

Solution in Swift 4.2 with O(N) complexity

public func solution(_ S : inout String) -> Int {
    if S.isEmpty { return 1 }
    if S.count == 1 { return 0 }
    
    var stack: [Character] = []
    
    for character in S {
        switch character {
        case "}":
            if !stack.isEmpty && stack.last == "{" {
                stack.popLast()
            } else {
                return 0
            }
        case "]":
            if !stack.isEmpty && stack.last == "[" {
                stack.popLast()
            } else {
                return 0
            }
        case ")":
            if !stack.isEmpty && stack.last == "(" {
                stack.popLast()
            } else {
                return 0
            }
        default:
            stack.append(character)
        }
    }
    
    return stack.count == 0 ? 1 : 0
}

Result: https://app.codility.com/demo/results/trainingD8A27H-PUM/

Ahmed M. Hassan
  • 709
  • 9
  • 14