Valid Parenthesis Problem Index Out of Range (Go)

Issue

I was converting code for a problem I previously solved in Python into Go and ran into a runtime error: index out of range [1] with length 1 on this line

 if string(s[i]) == ")" && arr[len(s) - 1] == "("{

Here is the code in entirety.

func isValid(s string) bool {
    arr := make([]string, 0)
    if len(s) < 2 {
        return false 
    }

    for i := 0; i < len(s); i++ {

        if string(s[i]) == "(" || string(s[i]) == "[" || string(s[i]) == "{" {
            arr = append(arr, string(s[i]))
        } else if string(s[i]) == ")" || string(s[i]) == "]" || string(s[i]) == "}" {
            if len(arr) >= 1 { 
                if string(s[i]) == ")" && arr[len(s) - 1] == "("{ 
                    arr = arr[:len(arr) -1]
                } else if string(s[i]) == "]" && arr[len(s) - 1] == "[" {
                    arr = arr[:len(arr) -1]
                } else if string(s[i]) == "}" && arr[len(s) - 1] == "{" {
                    arr = arr[:len(arr) -1]
                }  else {
                    return false
                }
            }else {
                return false
            }
    }
    }
    if reflect.DeepEqual(arr, []string{""}) {
        return true
    } else  {
        return false
    }
    
}

What is the cause of the issue?

Solution

You’ve used len(s)-1 to find the last index of arr, but it should be len(arr)-1.

Here’s a working version of your code, that fixes some additional bugs, and avoids needless conversion to string for single characters. https://go.dev/play/p/sazf2RguoIr

package main

import "fmt"

func isValid(s string) bool {
    var arr []rune
    for _, c := range s {
        if c == '(' || c == '[' || c == '{' {
            arr = append(arr, c)
        } else if c == ')' || c == ']' || c == '}' {
            if len(arr) == 0 {
                return false
            }
            var last rune
            arr, last = arr[:len(arr)-1], arr[len(arr)-1]
            if c == ')' && last != '(' || c == ']' && last != '[' || c == '}' && last != '{' {
                return false
            }
        }
    }
    return len(arr) == 0
}

func main() {
    cases := []string{
        "()[({}())]",
        "(]",
        "((())",
        "{{{}}}",
        "{{{[][][]}}}",
    }
    for _, c := range cases {
        fmt.Println(c, isValid(c))
    }
}

Answered By – Paul Hankin

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.