<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>LeetCode on 怠惰技術ブログ</title>
    <link>/tags/leetcode/</link>
    <description>Recent content in LeetCode on 怠惰技術ブログ</description>
    <generator>Hugo -- 0.147.7</generator>
    <language>ja</language>
    <lastBuildDate>Tue, 13 Jan 2026 19:30:00 +0900</lastBuildDate>
    <atom:link href="/tags/leetcode/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>LeetCode 735: Asteroid Collision - スタックで衝突判定を美しく解く</title>
      <link>/posts/2026-01-13-leetcode-735/</link>
      <pubDate>Tue, 13 Jan 2026 19:30:00 +0900</pubDate>
      <guid>/posts/2026-01-13-leetcode-735/</guid>
      <description>&lt;h2 id=&#34;問題概要&#34;&gt;問題概要&lt;/h2&gt;
&lt;p&gt;整数で表される小惑星の配列 &lt;code&gt;asteroids&lt;/code&gt; が与えられる。各小惑星について：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;絶対値：大きさ&lt;/li&gt;
&lt;li&gt;符号：方向（正=右、負=左）&lt;/li&gt;
&lt;li&gt;全て同じ速度で移動&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;衝突ルール：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小さい方が爆発&lt;/li&gt;
&lt;li&gt;同じ大きさなら両方爆発&lt;/li&gt;
&lt;li&gt;同じ方向に移動する小惑星は衝突しない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;全ての衝突後の状態を返せ。&lt;/p&gt;
&lt;h2 id=&#34;失敗した実装&#34;&gt;失敗した実装&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; collections &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; deque
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;asteroidCollision&lt;/span&gt;(self, asteroids: List[int]) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; List[int]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        stack &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; aster &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; asteroids:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(stack) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; (aster &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; (stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(aster)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; len(stack) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; (aster &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; (stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; abs(aster) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; abs(stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(stack) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; (stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; (aster &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(aster)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; abs(aster) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; abs(stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;問題点&#34;&gt;問題点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;同じ条件判定 &lt;code&gt;if len(stack) &amp;lt;= 0 or (stack[-1] &amp;lt;= 0) == (aster &amp;lt;= 0)&lt;/code&gt; が2箇所に重複&lt;/li&gt;
&lt;li&gt;制御フローが複雑で読みにくい&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(aster &amp;lt;= 0) != (stack[-1] &amp;lt;= 0)&lt;/code&gt; は「符号が異なる」を検出するが、衝突しないケースも含む&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;最適解&#34;&gt;最適解&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;asteroidCollision&lt;/span&gt;(self, asteroids: List[int]) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; List[int]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        stack &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; asteroid &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; asteroids:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; stack &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; asteroid &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#75715e&#34;&gt;# 右向き vs 左向きの衝突が発生&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; abs(stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; abs(asteroid):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;# 右向きが小さい → 爆発して次の右向きとも衝突判定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; abs(stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; abs(asteroid):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;# 同じ大きさ → 両方爆発&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#75715e&#34;&gt;# 衝突しなかった or 左向きが勝った&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                stack&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(asteroid)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;わかったこと&#34;&gt;わかったこと&lt;/h2&gt;
&lt;h3 id=&#34;1-ループ条件の本質&#34;&gt;1. ループ条件の本質&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;asteroid &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; stack[&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これは &lt;code&gt;(asteroid &amp;lt; 0) and (0 &amp;lt; stack[-1])&lt;/code&gt; と同じ。つまり：&lt;/p&gt;</description>
    </item>
    <item>
      <title>DFS/BFSの本質：深さと幅を支配するデータ構造の選択</title>
      <link>/posts/2026-01-09-dfs-bfs/</link>
      <pubDate>Fri, 09 Jan 2026 06:30:00 +0900</pubDate>
      <guid>/posts/2026-01-09-dfs-bfs/</guid>
      <description>&lt;p&gt;DFS, BFSがわかりづらかったので、いくつかの記事を見て個人的に感じた疑問や
「こういうコード例が欲しい」という要望を踏まえて生成AIに生成してもらった。&lt;/p&gt;
&lt;p&gt;生成された内容を検証し、コードを実際に動かして確認したところ、
自分の理解が深まる良い記事になったので、このまま公開することにした。&lt;/p&gt;
&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;LeetCodeでMedium問題を解いていると、必ず遭遇するのがDFS（深さ優先探索）とBFS（幅優先探索）だ。&lt;/p&gt;
&lt;p&gt;「Dは深さ、Bは幅」というのは知っている。でも、&lt;strong&gt;なぜスタックとキューを使い分けるのか&lt;/strong&gt;？その本質を理解している人は意外と少ない。&lt;/p&gt;
&lt;p&gt;今回は、入れ子リストの例を使って、DFS/BFSの動作原理とデータ構造の関係を視覚的に解説する。&lt;/p&gt;
&lt;h2 id=&#34;問題設定入れ子リストをフラット化する&#34;&gt;問題設定：入れ子リストをフラット化する&lt;/h2&gt;
&lt;p&gt;以下のような入れ子構造のリストがあるとする。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, [&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, [&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;], &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;], &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これをフラットな配列にしたい。このとき、「どの順番で要素を取り出すか」がDFS/BFSの違いだ。&lt;/p&gt;
&lt;h2 id=&#34;ツリー構造として可視化する&#34;&gt;ツリー構造として可視化する&lt;/h2&gt;
&lt;p&gt;入れ子リストは、実はツリー構造として表現できる。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;        root
       / | \
      1  []  3
         |
        /|\ \
       4 5 [] 2
           |
          /|\
         6 7 8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;この木をどう巡回するかで、DFSとBFSが決まる。&lt;/p&gt;
&lt;h2 id=&#34;dfs深さ優先探索とにかく深く潜る&#34;&gt;DFS（深さ優先探索）：とにかく深く潜る&lt;/h2&gt;
&lt;h3 id=&#34;動作イメージ&#34;&gt;動作イメージ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;「見つけた枝があれば、まずそこを最後まで探索する」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;訪問順序：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1 → [中に入る] → 4 → 5 → [さらに中] → 6 → 7 → 8 
→ [戻る] → 2 → [戻る] → 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;結果：&lt;code&gt;[1, 4, 5, 6, 7, 8, 2, 3]&lt;/code&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
