Conversation
nanae772
left a comment
There was a problem hiding this comment.
お疲れ様です、Javaはあまり詳しくないですが全体的に読みやすく自然なコードだと思いました。分かりやすかったです。
この問題については再帰下降構文解析という解き方もあるのでそちらも見ておくと勉強になるかもしれません
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.5ynll0rwu02h
| ```java | ||
| class Solution { | ||
| public boolean isValid(String s) { | ||
| Stack<Character> stack = new Stack<>(); |
There was a problem hiding this comment.
Javaは詳しくないのですが、過去に講師の方の以下のようなコメントがあったのでArrayDequeを使ったほうがよいのかもしれません
スタックデータ構造であれば、 Stack より ArrayDeque を優先的に使うことをおすすめします。
kt-from-j/leetcode#4 (comment)
There was a problem hiding this comment.
少し気になってそれぞれのpop処理を軽く見たのですが、
ArrayDequeで内部で呼ばれるpollFirst()は先頭の値を取り出した後にheadのindexを前に進めるだけなのに対して、Stackで内部で呼ばれるVectorのremoveElementAt()では値をnullにするなどより複雑な処理をしているようです。
There was a problem hiding this comment.
お二人とも、ご確認ありがとうございますmm
Javaについて調べていただき助かりますmm
Javaは詳しくないのですが、過去に講師の方の以下のようなコメントがあったのでArrayDequeを使ったほうがよいのかもしれません
ご指摘非常に助かります! 🙇
確かに公式ドキュメントにも記載がありました
今後はStackではなくArrayDequeを使います。
このクラスは通常、スタックとして使われるときはStackよりも高速で、キューとして使われるときはLinkedListよりも高速です。
https://docs.oracle.com/javase/jp/17/docs/api/java.base/java/util/ArrayDeque.html
ArrayDequeで内部で呼ばれるpollFirst()は先頭の値を取り出した後にheadのindexを前に進めるだけなのに対して、Stackで内部で呼ばれるVectorのremoveElementAt()では値をnullにするなどより複雑な処理をしているようです。
ソースコードまで見ていただきありがとうございます! 🙇
ご指摘のとおりVectorでは public synchronized void removeElementAt(int index) とスレッドセーフにするためにsynchronizedを使ってロックを取得しスレッド間で同期をとっているため、スレッドセーフでない(ロックを取らない)ArrayDequeに比べてパフォーマンスが落ちると理解できました。
| public boolean isValid(String s) { | ||
| Stack<Character> stack = new Stack<>(); | ||
| Map<Character, Character> closeToOpen = new HashMap<>(); | ||
| closeToOpen.put(']', '['); |
There was a problem hiding this comment.
閉じ括弧→開き括弧は普段と順序が逆になっており、ぱっと見で対応が取れているか分かりづらい面もあるかと思います。
その1つの解決策としてopenToCloseにして、stackからpopした開き括弧をopenToCloseに今見ている閉じ括弧と対応しているかを見る方法もあるかなと思いました。
| closeToOpen.put(')', '('); | ||
| for (Character c : s.toCharArray()) { | ||
| if (closeToOpen.containsKey(c)) { | ||
| if (!stack.isEmpty() && stack.peek() == closeToOpen.get(c)){ |
There was a problem hiding this comment.
ここで直接stack.pop()してその値を比較して違ったらreturn Falseを返すとするとelse分岐が要らなくなりそうです
There was a problem hiding this comment.
ご指摘ありがとうございますmm
この発想はなかったです!
| ```java | ||
| class Solution { | ||
| public boolean isValid(String s) { | ||
| Stack<Character> stack = new Stack<>(); |
There was a problem hiding this comment.
少し気になってそれぞれのpop処理を軽く見たのですが、
ArrayDequeで内部で呼ばれるpollFirst()は先頭の値を取り出した後にheadのindexを前に進めるだけなのに対して、Stackで内部で呼ばれるVectorのremoveElementAt()では値をnullにするなどより複雑な処理をしているようです。
|
講師陣はこの問題を見るとプッシュダウンオートマトンという単語を想起するみたいです。 |
https://leetcode.com/problems/valid-parentheses/description/