diff --git a/20ValidParentheses.md b/20ValidParentheses.md new file mode 100644 index 0000000..06a4981 --- /dev/null +++ b/20ValidParentheses.md @@ -0,0 +1,90 @@ +### Step 1 +- stackのカテゴリの問題であるというヒントもあり、すぐに方針は立った +- 実装も割とすぐにできた +- 他のArai60の問題はgolangで解いてきたが、golangでの文字列処理は面倒なのでPythonを使うことにした + +```Python3 +class Solution: + def isValid(self, s: str) -> bool: + brackets = { + ")": "(", + "}": "{", + "]": "[" + } + stack: List[str] = [] + for i in range(len(s)): + if s[i] in brackets.keys(): + if len(stack) == 0: + return False + c = stack.pop() + if brackets[s[i]] != c: + return False + else: + stack.append(s[i]) + return len(stack) == 0 +``` + +### Step 2 +- コードを整えつつ、discordで先人達のコードも参考にした +- close_to_openのマップよりopen_to_closeを使っているコードを多く見たのでそちらを試してみる + - if文をネストさせずに済んだのでこっちの方が良いだろう +- Pythonの好きでない点として、同じことをやろうとしても選択肢が多すぎるという点を挙げられるが、今回もまさしくそう + - スタックを普通のリストを使って実現するか、deque()を使うか、LifoQueueを使うか、、 + - 下記コードのようにLifoQueueを使うと、宣言時にこれはスタックであるということをリスト名にstackという言葉を入れなくてもわかるのが利点。欠点としては、メソッドがput, getでスタックぽくない + - 逆にリストやdeque()を使うと、スタックであるということを別の方法(命名やコメント)で伝えないといけなかったり、誤ってスタックではしない動作をさせてしまう可能性があるのが難点 + +```Python3 +from queue import LifoQueue + + +class Solution: + def isValid(self, s: str) -> bool: + open_to_close = { + "(": ")", + "{": "}", + "[": "]" + } + open_brackets = LifoQueue() + + for i in range(len(s)): + if s[i] in open_to_close: + open_brackets.put(s[i]) + continue + if open_brackets.empty(): + return False + c = open_brackets.get() + if s[i] != open_to_close[c]: + return False + + return open_brackets.empty() +``` + +### Step 3 +- `for i in range(len(s))`を`for c in s`に変えて、Pythonらしくシンプルさを追求した +- `if c in open_to_close.keys()`もより短く`if c in open_to_close`に変えた + +```Python3 +from queue import LifoQueue + + +class Solution: + def isValid(self, s: str) -> bool: + open_to_close = { + "(": ")", + "{": "}", + "[": "]" + } + open_brackets = LifoQueue() + + for c in s: + if c in open_to_close: + open_brackets.put(c) + continue + if open_brackets.empty(): + return False + top = open_brackets.get() + if c != open_to_close[top]: + return False + + return open_brackets.empty() +``` diff --git a/go.md b/go.md new file mode 100644 index 0000000..be07639 --- /dev/null +++ b/go.md @@ -0,0 +1,32 @@ +- goでも解いてみました + +```Go +func isValid(s string) bool { + openToClose := map[rune]rune{ + '(': ')', + '{': '}', + '[': ']', + } + openBracketsStack := []rune{} + + for _, c := range s { + if _, exist := openToClose[c]; exist { + openBracketsStack = append(openBracketsStack, c) + continue + } + + l := len(openBracketsStack) + if l == 0 { + return false + } + + top := openBracketsStack[l-1] + openBracketsStack = openBracketsStack[:l-1] + if c != openToClose[top] { + return false + } + } + + return len(openBracketsStack) == 0 +} +``` diff --git a/step4.md b/step4.md new file mode 100644 index 0000000..0552426 --- /dev/null +++ b/step4.md @@ -0,0 +1,79 @@ +### Step 4 +- step1~3ではスタックを自作する必要のあるGoを避けてPythonを使ったが、他の問題はGoで解いてきたのでGoでやることに。 +- スタックも自作した + +```Go +type runeStack []rune + +func (s runeStack) Empty() bool { return len(s) == 0 } + +func (s *runeStack) Push(r rune) { + *s = append(*s, r) +} + +func (s *runeStack) Pop() (rune, error) { + l := len(*s) + if l == 0 { + return rune(0), errors.New("Empty Stack") + } + + last := (*s)[l-1] + *s = (*s)[:l-1] + return last, nil +} + +func isValid(s string) bool { + openToClose := map[rune]rune{ + '(': ')', + '{': '}', + '[': ']', + } + openBracketStack := &runeStack{} + + for _, c := range s { + if _, exist := openToClose[c]; exist { + openBracketStack.Push(c) + continue + } + + last, err := openBracketStack.Pop() + if err != nil || c != openToClose[last] { + return false + } + } + + return openBracketStack.Empty() +} +``` + +- ちなみにスタックを自作せずスライスを使うと下のようになる。 +- スタックを自作すると手間はかかるが、可読性は増すということを実感した + +```Go +func isValid(s string) bool { + openToClose := map[rune]rune{ + '(': ')', + '{': '}', + '[': ']', + } + openBracketStack := []rune{} + + for _, c := range s { + if _, exist := openToClose[c]; exist { + openBracketStack = append(openBracketStack, c) + continue + } + l := len(openBracketStack) + if l == 0 { + return false + } + last := openBracketStack[l-1] + openBracketStack = openBracketStack[:l-1] + if c != openToClose[last] { + return false + } + } + + return len(openBracketStack) == 0 +} +```