<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>String on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/string/</link><description>Recent content in String on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sat, 12 Dec 2020 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/string/index.xml" rel="self" type="application/rss+xml"/><item><title>從LeetCode學演算法 - 107 String (7) / Stack (2)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-107-string-7-stack-2/</link><pubDate>Sat, 12 Dec 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-107-string-7-stack-2/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 107 String (7) / Stack (2)" /&gt;&lt;p&gt;&lt;strong&gt;1544. Make The String Great (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;好久不見啦！最近筆者比較忙碌，還請多多見諒XD&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;抽獎活動還在繼續累積人數(現在好像沒有人想抽XD)&lt;br&gt;
在&lt;a class="link" href="https://www.facebook.com/groups/pythontw/permalink/10160354153893438/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Python Taiwan的連結第100篇的文章&lt;/strong&gt; &lt;/a&gt;底下，&lt;br&gt;
&lt;strong&gt;公開分享到你的臉書、按讚該篇文章、並留言告訴我說，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;「你最喜歡這一整個系列的哪一篇？為什麼？」或&lt;br&gt;
「除了從LeetCode學演算法系列以外，&lt;br&gt;
你還想要看到關於什麼方向的文章？」&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;超過20則留言的話&lt;/strong&gt; (有完成以上步驟的才算)，我們就抽一組&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;br&gt;
課程的免費兌換券進行贈送！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;期限嘛…就延長到滿人數吧XDD (不然也沒辦法哈哈)&lt;/p&gt;
&lt;p&gt;容筆者工商一下，&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」&lt;/strong&gt; 開放預購啦！&lt;br&gt;
這次選了40道難度加深的LeetCode題目，&lt;br&gt;
同樣也會細部解說對應的技巧及須要掌握的演算法！&lt;br&gt;
同時這次購買進階篇的話，&lt;br&gt;
額外還加贈**「從Leetcode學演算法｜面試篇」** ！&lt;br&gt;
當中包含了&lt;strong&gt;面試準備須知分享&lt;/strong&gt; ，&lt;strong&gt;及訪談國內外不同經驗的工程師&lt;/strong&gt; ，&lt;br&gt;
讓你不論是&lt;strong&gt;想走前端/後端/一般軟工&lt;/strong&gt; 或者是&lt;strong&gt;想找國外的工作&lt;/strong&gt; ，&lt;br&gt;
是&lt;strong&gt;初學想轉職&lt;/strong&gt; 還是&lt;strong&gt;正在工作&lt;/strong&gt; ，都能夠從中得到收穫呦！&lt;br&gt;
有興趣的朋友可以使用下面的早鳥優惠～&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;/strong&gt; ：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/leetcodeadv" target="_blank" rel="noopener"
&gt;https://bit.ly/leetcodeadv&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://bit.ly/leetcodeall" target="_blank" rel="noopener"
&gt;https://bit.ly/leetcodeall&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a string &lt;code&gt;s&lt;/code&gt; of lower and upper case English letters.&lt;/p&gt;
&lt;p&gt;A good string is a string which doesn’t have &lt;strong&gt;two adjacent characters&lt;/strong&gt; &lt;code&gt;s[i]&lt;/code&gt; and &lt;code&gt;s[i + 1]&lt;/code&gt; where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= i &amp;lt;= s.length - 2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s[i]&lt;/code&gt; is a lower-case letter and &lt;code&gt;s[i + 1]&lt;/code&gt; is the same letter but in upper-case or &lt;strong&gt;vice-versa&lt;/strong&gt; .&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make the string good, you can choose &lt;strong&gt;two adjacent&lt;/strong&gt; characters that make the string bad and remove them. You can keep doing this until the string becomes good.&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;the string&lt;/em&gt; after making it good. The answer is guaranteed to be unique under the given constraints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notice&lt;/strong&gt; that an empty string is also good.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;leEeetcode&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;leetcode&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: In the first step, either you choose i = 1 or i = 2, both will result &amp;#34;leEeetcode&amp;#34; to be reduced to &amp;#34;leetcode&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;abBAcC&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: We have many possible scenarios, and all lead to the same answer. For example:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;#34;abBAcC&amp;#34; --&amp;gt; &amp;#34;aAcC&amp;#34; --&amp;gt; &amp;#34;cC&amp;#34; --&amp;gt; &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;#34;abBAcC&amp;#34; --&amp;gt; &amp;#34;abBA&amp;#34; --&amp;gt; &amp;#34;aA&amp;#34; --&amp;gt; &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;s&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;s&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= s.length &amp;lt;= 100&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; contains only lower and upper case English letters.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個字串s，當中含有大小寫的英文字母，&lt;br&gt;
一個好的字串被定義為對於 &lt;strong&gt;0 ≤ i ≤ s.length - 2&lt;/strong&gt; 來說，&lt;br&gt;
兩個相鄰的字元s[i]和s[i+1]不會含有相同字母但大小寫相反的狀況，&lt;br&gt;
例如aA, Cc這種型式。&lt;/p&gt;
&lt;p&gt;要讓字串變好，可以透過每次拿掉兩個相鄰且讓字串變壞的字元達到，&lt;br&gt;
最終得到一個好的字串。&lt;/p&gt;
&lt;p&gt;題目表示給定的題目一定有答案且必然是唯一的。&lt;br&gt;
(空字串也是好的字串)&lt;/p&gt;
&lt;p&gt;說起來這題的標題不禁讓人想到美國總統大選，&lt;br&gt;
不過到現在恐怕已經大勢底定了就是，&lt;br&gt;
這句話恐怕就要成為絕響了吧XD&lt;/p&gt;
&lt;p&gt;扯遠了，我們來看看這題。&lt;/p&gt;
&lt;p&gt;由於它已經保證會有唯一解，&lt;br&gt;
那麼相鄰字元的移除順序理論上並不會影響結果，&lt;br&gt;
所以直觀上好像可以每次掃過一遍字串，&lt;br&gt;
將大小寫相鄰的相同字母移掉就解決了&amp;hellip;&amp;hellip;嗎？&lt;/p&gt;
&lt;p&gt;但這麼做的話，我們會不知道要掃過幾次字串才能夠將所有問題移除完，&lt;br&gt;
因為比如碰到&lt;strong&gt;abBA&lt;/strong&gt; 這樣子的字串，我們要將**’bB’** 移除掉，&lt;br&gt;
才會在下一次發現**’aA’** 可以移除。&lt;/p&gt;
&lt;p&gt;所以為求簡單起見，&lt;br&gt;
我們可以使用一個&lt;strong&gt;Stack&lt;/strong&gt; 來存放已經檢查過的部分，&lt;br&gt;
每次放一個字元到Stack中，存放前將Stack最上面的那個字元，&lt;br&gt;
跟準備要放的字元做比較：&lt;br&gt;
&lt;strong&gt;兩者是相同字母且大小寫相反-&amp;gt;將Stack中最上面的字元pop掉&lt;br&gt;
兩者不需相消-&amp;gt;放入Stack&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這麼一來，我們就只會放沒有讓字串變壞的字元進到Stack，&lt;br&gt;
同時每次都會拿新的字元跟前面的比對，以排除掉應該移除的部分。&lt;/p&gt;
&lt;p&gt;那麼，怎麼算大小寫相反呢？&lt;br&gt;
除了用upper/lower case相關的函式外，&lt;br&gt;
&lt;strong&gt;在&lt;/strong&gt; &lt;a class="link" href="https://zh.wikipedia.org/wiki/ASCII" target="_blank" rel="noopener"
&gt;&lt;strong&gt;ASCII Code&lt;/strong&gt; &lt;/a&gt;&lt;strong&gt;中，相同大小寫的字母的對應碼會恰巧差32。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;為什麼不是26? 因為中間還有帶一些標點符號。&lt;/strong&gt; Python中我們可以使用ord()來對一個字元取其ASCII Code值，&lt;br&gt;
而在Java中，我們可以視char為一個數字來進行加減運算，&lt;br&gt;
所以直接相加減就可以了。&lt;/p&gt;
&lt;p&gt;可能有讀者會問：&lt;br&gt;
&lt;strong&gt;「那我記不住32這個數字怎麼辦？」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在寫的過程中，我們也可以用’a’和’A’的位置差算出來，&lt;br&gt;
注意**’a’對應的值是比較大** 的呦！&lt;br&gt;
所以可以將其寫成：&lt;strong&gt;&amp;lsquo;a&amp;rsquo; - &amp;lsquo;A&amp;rsquo; (Java)或 ord(‘a’)- ord(‘A’) (Python)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你再問：&lt;br&gt;
&lt;strong&gt;「那我記不住哪個在前面怎麼辦？」&lt;/strong&gt;&lt;br&gt;
呃……那你只好再&lt;strong&gt;加個絕對值&lt;/strong&gt; 了！&lt;br&gt;
使用Math.abs() (Java) 或 abs() (Python)就可以囉！&lt;/p&gt;
&lt;p&gt;因此，流程大體如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立一個stack名為st&lt;/li&gt;
&lt;li&gt;從字串s當中依序取出字元c，進行迴圈：&lt;br&gt;
2-1. 當st不為空，且最上面的值和c的值&lt;strong&gt;相差32&lt;/strong&gt; 時，就對st進行pop&lt;br&gt;
2-2. 否則表示不需消除，將c推入st中(push)&lt;/li&gt;
&lt;li&gt;完成迴圈後，將st的所有字元連起來得到的字串即為答案&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，由於Java的Stack固定從尾端取出，&lt;br&gt;
最終使用StringBuilder進行組合完以後，toString之前記得要reverse，&lt;br&gt;
不然答案就會反掉囉XD！&lt;br&gt;
當然，也可以採用ArrayDeque來做，&lt;br&gt;
這樣就可以從頭排列到尾而不需要反轉。&lt;br&gt;
使用peek()可以幫助我們確認stack的最上面一個值是什麼，&lt;br&gt;
而不會將其取出，同時因不確定大小寫誰在前面，&lt;br&gt;
所以檢查時要記得取絕對值！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/3c225e5679bc20afbbef6839ca86f140.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python這邊多加了一條判斷，但其實不影響，&lt;br&gt;
只是s的長度是1或0時都可以直接回傳就是了XD&lt;/p&gt;
&lt;p&gt;我們可以看到對於Python來說好處就是可以直接拿list當stack來使用，&lt;br&gt;
同時，使用join函式可以簡單地將list組成字串。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/f7e2c4a352a01676f7dde17345c9f762.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(N)，N為字串長度。Java也可以使用CharAt(i)的型式來處理取出字元的部分，但不影響空間複雜度，因為後面還有其他要組的部分XD)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;想看看其他題目嗎？&lt;br&gt;
歡迎從&lt;a class="link" href="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-0/" &gt;&lt;strong&gt;第零篇&lt;/strong&gt; &lt;/a&gt;找你想要的！&lt;/p&gt;
&lt;p&gt;同時追蹤粉專以獲得更多新文章的通知：&lt;br&gt;
&lt;a class="link" href="https://www.facebook.com/learnwithdesolve" target="_blank" rel="noopener"
&gt;&lt;strong&gt;跟著Desolve學程式&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外，&lt;strong&gt;「從Leetcode學演算法｜基礎篇」&lt;/strong&gt; 已經回原價囉，&lt;br&gt;
先前的優惠碼會失效，但這邊仍然為讀者保留了300塊的折抵，&lt;br&gt;
雖然&lt;strong&gt;整捆一起買總體比較划算&lt;/strong&gt; (差290而已就有整組了阿XD)，&lt;br&gt;
如果你還是想先試試基礎課的話，&lt;br&gt;
&lt;strong&gt;300元折抵的連結&lt;/strong&gt; 在這邊：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/1desolve" target="_blank" rel="noopener"
&gt;https://bit.ly/1desolve&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 101 String (6)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-101-string-6/</link><pubDate>Sun, 26 Jul 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-101-string-6/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 101 String (6)" /&gt;&lt;p&gt;&lt;strong&gt;1529. Bulb Switcher IV (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;抽獎活動還在繼續累積人數(現在好像沒有人想抽XD)&lt;br&gt;
在&lt;a class="link" href="https://www.facebook.com/groups/pythontw/permalink/10160354153893438/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Python Taiwan的連結第100篇的文章&lt;/strong&gt; &lt;/a&gt;底下，&lt;br&gt;
&lt;strong&gt;公開分享到你的臉書、按讚該篇文章、並留言告訴我說，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;「你最喜歡這一整個系列的哪一篇？為什麼？」或&lt;br&gt;
「除了從LeetCode學演算法系列以外，&lt;br&gt;
你還想要看到關於什麼方向的文章？」&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;超過20則留言的話&lt;/strong&gt; (有完成以上步驟的才算)，我們就抽一組&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;br&gt;
課程的免費兌換券進行贈送！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;截止時間為7/31 23:59:59，這之後的留言問題我有看到還是會回答，&lt;br&gt;
但就不會納入抽獎資格歐！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;容筆者工商一下，&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」&lt;/strong&gt; 開放預購啦！&lt;br&gt;
這次選了40道難度加深的LeetCode題目，&lt;br&gt;
同樣也會細部解說對應的技巧及須要掌握的演算法！&lt;br&gt;
同時這次購買進階篇的話，&lt;br&gt;
額外還加贈**「從Leetcode學演算法｜面試篇」** ！&lt;br&gt;
當中包含了&lt;strong&gt;面試準備須知分享&lt;/strong&gt; ，&lt;strong&gt;及訪談國內外不同經驗的工程師&lt;/strong&gt; ，&lt;br&gt;
讓你不論是&lt;strong&gt;想走前端/後端/一般軟工&lt;/strong&gt; 或者是&lt;strong&gt;想找國外的工作&lt;/strong&gt; ，&lt;br&gt;
是&lt;strong&gt;初學想轉職&lt;/strong&gt; 還是&lt;strong&gt;正在工作&lt;/strong&gt; ，都能夠從中得到收穫呦！&lt;/p&gt;
&lt;p&gt;當前面試篇以上傳完畢，進階篇則會在8/31前陸續上傳完成呦！&lt;/p&gt;
&lt;p&gt;有興趣的朋友可以使用下面的早鳥優惠～&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;/strong&gt; ：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/advleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/advleetcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://bit.ly/allleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/allleetcode&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;There is a room with &lt;code&gt;n&lt;/code&gt; bulbs, numbered from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n-1&lt;/code&gt;, arranged in a row from left to right. Initially all the bulbs are &lt;strong&gt;turned off&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;Your task is to obtain the configuration represented by &lt;code&gt;target&lt;/code&gt; where &lt;code&gt;target[i]&lt;/code&gt; is &amp;lsquo;1&amp;rsquo; if the i-th bulb is turned on and is &amp;lsquo;0&amp;rsquo; if it is turned off.&lt;/p&gt;
&lt;p&gt;You have a switch to flip the state of the bulb, a flip operation is defined as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;any&lt;/strong&gt; bulb (index &lt;code&gt;i&lt;/code&gt;) of your current configuration.&lt;/li&gt;
&lt;li&gt;Flip each bulb from index &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;n-1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When any bulb is flipped it means that if it is 0 it changes to 1 and if it is 1 it changes to 0.&lt;/p&gt;
&lt;p&gt;Return the &lt;strong&gt;minimum&lt;/strong&gt; number of flips required to form &lt;code&gt;target&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: target = &amp;#34;10111&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: Initial configuration &amp;#34;00000&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flip from the third bulb: &amp;#34;00000&amp;#34; -&amp;gt; &amp;#34;00111&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flip from the first bulb: &amp;#34;00111&amp;#34; -&amp;gt; &amp;#34;11000&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flip from the second bulb: &amp;#34;11000&amp;#34; -&amp;gt; &amp;#34;10111&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;We need at least 3 flip operations to form target.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: target = &amp;#34;101&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: &amp;#34;000&amp;#34; -&amp;gt; &amp;#34;111&amp;#34; -&amp;gt; &amp;#34;100&amp;#34; -&amp;gt; &amp;#34;101&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: target = &amp;#34;00000&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-4"&gt;Example 4
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: target = &amp;#34;001011101&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= target.length &amp;lt;= 10^5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target[i] == '0'&lt;/code&gt; or &lt;code&gt;target[i] == '1'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;這題是今天(2020/07/26)舉辦的199th LeetCode Weekly Contest的第2題。&lt;br&gt;
房間裡有n個燈泡**(0~n-1)** ，從左至右排列，&lt;strong&gt;初始全數是關的&lt;/strong&gt; 。&lt;br&gt;
我們的目標是將燈開關成&lt;strong&gt;target&lt;/strong&gt; 的狀態，在index i的位置上，&lt;br&gt;
target[i]如果是'1&amp;rsquo;的話就表示開，target[i]如果是'0&amp;rsquo;的話就表示關。&lt;/p&gt;
&lt;p&gt;所能夠做的操作只有一種叫&lt;strong&gt;flip&lt;/strong&gt; 的方法。&lt;br&gt;
flip方法的操作是選取一個index i，&lt;br&gt;
接著會將&lt;strong&gt;i~n-1的所有燈泡狀態反轉，1變成0，0變成1&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;我們要作的事情是找出最少完成target的flip次數。&lt;/p&gt;
&lt;p&gt;是說每次碰到稍微生活化一點的題目，就會覺得有點87：&lt;br&gt;
像這題亮燈就亮燈，搞那麼麻煩的開關方式幹嘛啦！！！&lt;br&gt;
不怕燈泡壞掉逆？？？&lt;/p&gt;
&lt;p&gt;這題乍看之下好像不容易，&lt;br&gt;
但仔細一看，flip的操作只影響該點及其右側的燈泡，&lt;br&gt;
所以我們由左往右看的話，只需要考慮&lt;strong&gt;當前該燈泡需不需要翻轉&lt;/strong&gt; 即可，&lt;br&gt;
因為某個點右側的燈泡flip不會影響該點。&lt;/p&gt;
&lt;p&gt;由於&lt;strong&gt;右邊的會一起反轉&lt;/strong&gt; ，所以我們可以定位一個&lt;strong&gt;flag=1&lt;/strong&gt; ，&lt;br&gt;
一開始大家都是0，所以第一次我們要翻轉的狀況，&lt;br&gt;
就是碰到&lt;strong&gt;target[i]和flag相等時。&lt;/strong&gt; 把右側翻過來以後，我們可以&lt;strong&gt;將flag從'1&amp;rsquo;變成'0&amp;rsquo;，&lt;/strong&gt;&lt;br&gt;
因為我們只要&lt;strong&gt;考慮翻或不翻&lt;/strong&gt; ，所以使用&lt;strong&gt;flag的變化&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;和target[i]碰到的値來作對照&lt;/strong&gt; 會相當方便：&lt;br&gt;
只要&lt;strong&gt;碰到和flag相同的就代表要加翻一次&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;不同的就代表不用翻&lt;/strong&gt; ，這樣沿路走到尾端，就可以得到計數的答案。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分使用charAt可以按char來取出每個字元，&lt;br&gt;
請留意要比較的時候要取成int，這邊直接減去’0’即可。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/3e614bbf0081bb52a5b31742bbe5b3c9.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分直接用int進行轉換字元成整數即可。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/04a5a55c90c881ab1661f4271cd2e10f.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(len(target))/O(1)，除了flag跟cnt以外並未額外再多用到其他空間)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;另外，&lt;strong&gt;「從Leetcode學演算法｜基礎篇」&lt;/strong&gt; 已經回原價囉，&lt;br&gt;
先前的優惠碼會失效，但這邊仍然為讀者保留了300塊的折抵，&lt;br&gt;
雖然&lt;strong&gt;整捆一起買總體比較划算&lt;/strong&gt; (差290而已就有整組了阿XD)，&lt;br&gt;
如果你還是想先試試基礎課的話，&lt;br&gt;
&lt;strong&gt;300元折抵的連結&lt;/strong&gt; 在這邊：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/1desolve" target="_blank" rel="noopener"
&gt;https://bit.ly/1desolve&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 92 String (5)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-92-string-5/</link><pubDate>Sun, 03 May 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-92-string-5/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 92 String (5)" /&gt;&lt;p&gt;&lt;strong&gt;0680. Valid Palindrome II (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a non-empty string &lt;code&gt;s&lt;/code&gt;, you may delete &lt;strong&gt;at most&lt;/strong&gt; one character. Judge whether you can make it a palindrome.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: &amp;#34;aba&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: True
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: &amp;#34;abca&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: True
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: You could delete the character &amp;#39;c&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The string will only contain lowercase characters a-z. The maximum length of the string is 50000.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個非空白的字串s，最多可以從當中刪除掉一個字元，&lt;br&gt;
試判斷你能否讓這個字串變成一個回文。&lt;/p&gt;
&lt;p&gt;回文(Palindrome)先前已經&lt;a class="link" href="https://medium.com/@desolution/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-74-linked-list-8-27c4894da297" target="_blank" rel="noopener"
&gt;&lt;strong&gt;介紹過了&lt;/strong&gt; &lt;/a&gt;，&lt;br&gt;
就是符合「從尾到頭和從頭到尾看起來相同」即可，&lt;br&gt;
所以它可以是像是&lt;strong&gt;abcba&lt;/strong&gt; 的形式(中間有一個單獨的字元)，&lt;br&gt;
或者是&lt;strong&gt;abba&lt;/strong&gt; (成對兩兩相對)，這個概念在很多回文的題目都有用到，&lt;br&gt;
讀者可以多加留意。&lt;/p&gt;
&lt;p&gt;假設今天不能刪除任何字元的話，&lt;br&gt;
問題就會直接變成檢查字串是否是回文，&lt;br&gt;
那麼我們就可以直接設定兩個index i, j，&lt;br&gt;
當中&lt;strong&gt;i從0開始遞增，j從s.length()-1(或len(s)-1)開始遞減&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;依序對照對稱的位置檢查字元是否相等&lt;/strong&gt; 即可。&lt;br&gt;
(檢查到i, j交會都還兩兩對稱相等，則為回文)&lt;/p&gt;
&lt;p&gt;好，那麼問題來了：&lt;br&gt;
如果原先不是回文，需要刪掉一個字元才能變成回文呢？&lt;br&gt;
該刪哪個？&lt;br&gt;
有一句話說得好：&lt;br&gt;
「解決不了問題，就解決產生問題的人」(大誤)，&lt;br&gt;
既然我們只有一個可以刪的空間，&lt;br&gt;
那麼就只能等到有無法對應到的狀況才處理。&lt;br&gt;
舉例來說：&lt;br&gt;
abcc&lt;strong&gt;e&lt;/strong&gt; ba -&amp;gt; a-a, b-b, 在c-e這個地方沒有對應到，&lt;br&gt;
那麼有可能是c有問題，也有可能是e有問題，&lt;br&gt;
所以我們可以分成刪掉c或刪掉e的狀況來檢查。&lt;br&gt;
(因為實際上我們不會預先知道是誰有問題，也有可能都有問題)&lt;br&gt;
也就是說，&lt;br&gt;
當i, j沒辦法對應到時，我們可以選擇&lt;strong&gt;略過i&lt;/strong&gt; 的位置上的字元，&lt;br&gt;
或者&lt;strong&gt;略過j&lt;/strong&gt; 的位置上的字元。(因為只是要檢查，所以不用真的作刪除)&lt;br&gt;
&lt;strong&gt;略過i&lt;/strong&gt; 的話，我們就要嘗試拿&lt;strong&gt;i+1來和j做對應&lt;/strong&gt; ；&lt;br&gt;
&lt;strong&gt;略過j&lt;/strong&gt; 的話，則是拿&lt;strong&gt;i和j-1做對應&lt;/strong&gt; 。&lt;br&gt;
剩下的狀況，就是按照前面一般檢查回文的流程依序檢查，&lt;br&gt;
只要這兩條路&lt;strong&gt;其中一種&lt;/strong&gt; 可以讓s變為回文，答案就會是&lt;strong&gt;true&lt;/strong&gt; 。&lt;br&gt;
那麼，如果又碰到沒對應到的呢？&lt;/p&gt;
&lt;p&gt;那我們就只能說抱歉了XD~&lt;br&gt;
我們已經用掉了一次刪除的機會，&lt;br&gt;
後面再碰到對應不上的，當然就是不能成為回文囉！&lt;br&gt;
所以這題看似會產生分支，其實只會產生一次而已，&lt;br&gt;
因為我們只能刪一次而已，所以這題的時間複雜度並不高。&lt;/p&gt;
&lt;p&gt;依此，我們寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/9651f4de798ee3f0de7483dfa602687f.js"&gt;&lt;/script&gt;
&lt;p&gt;Java的部分求方便起見，使用了toCharArray()，&lt;br&gt;
我們將後續略過1個字元檢查的函式稱為isp(isPalindrome)，&lt;br&gt;
當validPalindrome內的迴圈檢查到不符合的時候，&lt;br&gt;
便呼叫isp來分支檢查；進入isp時，則只有所有剩下的字元兩兩對應，&lt;br&gt;
才會回傳true，否則一定會回傳false。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/5e6a346fd0f59d8135ef0d84b4abff17.js"&gt;&lt;/script&gt;
&lt;p&gt;Python的部分，一樣不要忘記被用到的子函式要先宣告在前面，&lt;br&gt;
其它和Java的解大同小異。&lt;/p&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(len(s))/O(1)，&lt;br&gt;
由於最多分支就只有一次，&lt;br&gt;
所以總體的複雜度還是跟字串長有關；&lt;br&gt;
Java的部分因為偷懶使用toCharArray()，&lt;br&gt;
所以空間複雜度也是O(len(s))，願意節省一點的話，&lt;br&gt;
也可以用CharAt()來取得某個位置的字元。)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;感謝大家對這系列文章的支持！這邊跟大家自我工商一下：&lt;/p&gt;
&lt;p&gt;筆者開設的系列同名線上課程：&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜基礎篇」已經上線啦！&lt;/strong&gt; 在這堂課中，你將學會利用十種演算法/資料結構來優化解題過程，&lt;br&gt;
並實際完整練習&lt;strong&gt;20題&lt;/strong&gt; 精選考古題，&lt;br&gt;
進而逐漸提升到不需提示也可以突破白板題，取得工作門票！&lt;br&gt;
&lt;strong&gt;Medium優惠(最後一波早鳥優惠了，不確定調回原價是什麼時候)：&lt;/strong&gt; &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 91 String (4)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-91-string-4/</link><pubDate>Sun, 19 Apr 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-91-string-4/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 91 String (4)" /&gt;&lt;p&gt;&lt;strong&gt;0678. Valid Parenthesis String (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a string containing only three types of characters: ‘(‘, ‘)’ and ‘*’, write a function to check whether this string is valid. We define the validity of a string by these rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Any left parenthesis &lt;code&gt;'('&lt;/code&gt; must have a corresponding right parenthesis &lt;code&gt;')'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Any right parenthesis &lt;code&gt;')'&lt;/code&gt; must have a corresponding left parenthesis &lt;code&gt;'('&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Left parenthesis &lt;code&gt;'('&lt;/code&gt; must go before the corresponding right parenthesis &lt;code&gt;')'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'*'&lt;/code&gt; could be treated as a single right parenthesis &lt;code&gt;')'&lt;/code&gt; or a single left parenthesis &lt;code&gt;'('&lt;/code&gt; or an empty string.&lt;/li&gt;
&lt;li&gt;An empty string is also valid.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: &amp;#34;()&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: True
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: &amp;#34;(*)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: True
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: &amp;#34;(*))&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: True
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The string size will be in the range [1, 100].&lt;/p&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個字串，當中僅含三種字元：&amp;rsquo;(&amp;rsquo;, ‘)’, ‘*’ (左括號，右括號及米字號)，試寫一個函式以檢查這個字串是否有效。&lt;br&gt;
一個字串要符合以下的規則才算是有效的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;任一個左括號都要有一個對應的右括號&lt;/li&gt;
&lt;li&gt;任一個右括號都要有一個對應的左括號&lt;/li&gt;
&lt;li&gt;左括號必須出現在其對應的右括號之前&lt;/li&gt;
&lt;li&gt;米字號(*)可以被視為單一個右括號、左括號、或空字串&lt;/li&gt;
&lt;li&gt;空字串也是有效的&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;綜合上面的描述，我們可以知道像是：&lt;br&gt;
‘)(’ -&amp;gt; 右括號還沒對應就出現在左括號前所以是False；&lt;br&gt;
但像是‘(()()*)’ 就會是True，&lt;br&gt;
仔細觀察可以發現，如果我們先不考慮米字號的部分，&lt;br&gt;
&lt;strong&gt;從左到右，左括號出現的次數必然 &amp;gt;= 右括號出現的次數。&lt;br&gt;
(因為要兩兩相對應，且右括號不能還沒對應到就出現在左括號之前)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以，如果是沒有米字號的話，這題會相當簡單：&lt;br&gt;
定義一個cnt(初始值為0)，由左至右，&lt;br&gt;
每次&lt;strong&gt;碰到左括號則+1，右括號則-1&lt;/strong&gt; ，中間如果cnt變為&lt;strong&gt;負數&lt;/strong&gt; ，&lt;br&gt;
則代表&lt;strong&gt;有右括號還沒對應到就出現了&lt;/strong&gt; ，則有效性是&lt;strong&gt;False&lt;/strong&gt; ；&lt;br&gt;
而遍歷整個字串到結尾時，&lt;br&gt;
如果&lt;strong&gt;cnt變為0&lt;/strong&gt; 的話則有效性是&lt;strong&gt;True&lt;/strong&gt; (剛好所有括號兩兩對應)，&lt;br&gt;
否則則為&lt;strong&gt;False&lt;/strong&gt; (還有未對應到的括號)。&lt;/p&gt;
&lt;p&gt;那麼，加上米字號的話該怎麼辦呢？&lt;br&gt;
我們可以先&lt;strong&gt;將所有的米字號當成左括號來用&lt;/strong&gt; ，&lt;br&gt;
由左至右檢查是否左括號足夠配對右括號完還有剩。&lt;br&gt;
假設&lt;strong&gt;中途左括號不夠的話&lt;/strong&gt; ，肯定是&lt;strong&gt;False&lt;/strong&gt; (因為加上米字號都不夠用)；&lt;br&gt;
&lt;strong&gt;配對完剛好用完&lt;/strong&gt; -&amp;gt; ** True**(因為所有的米字號全拿來當左括號剛好OK)&lt;br&gt;
配對完&lt;strong&gt;左括號還有剩&lt;/strong&gt; 呢？&lt;br&gt;
這時候我們應該&lt;strong&gt;從右至左，&lt;/strong&gt; 換成將&lt;strong&gt;所有的米字號當成右括號來用，&lt;br&gt;
換成檢查右括號足不足夠配對。&lt;br&gt;
中途右括號不夠 -&amp;gt; False；&lt;br&gt;
最後如果右括號數量足夠的話，則為True。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最後一段我們需要更仔細的考慮原因：&lt;br&gt;
有沒有可能在由左至右留下來多出來的部分是左括號呢？&lt;br&gt;
答案是否定的，因為如果是這樣的話，這些多出來的部分，&lt;br&gt;
在反方向的時候會因為它們不是米字號，使得&lt;strong&gt;右括號的數量不夠用&lt;/strong&gt; ，&lt;br&gt;
從而讓&lt;strong&gt;中途不足以配對&lt;/strong&gt; 的狀況發生。&lt;br&gt;
所以要嘛就是&lt;strong&gt;剛好完全配對&lt;/strong&gt; ，不然的話，就是&lt;strong&gt;剩下的全都是米字號&lt;/strong&gt; ，&lt;br&gt;
這樣反向時才有辦法處理。&lt;/p&gt;
&lt;p&gt;所以，當雙向都能夠順利滿足的時候，&lt;br&gt;
只要將多出來的米字號視作空字串，就能使整個字串得以滿足有效性了！&lt;/p&gt;
&lt;p&gt;依照上面的邏輯，我們可以進行 two pass 經過整個字串，&lt;br&gt;
完成整個檢查工作，其空間複雜度為O(1)，時間複雜度為O(n)。&lt;br&gt;
(n為字串的長度)&lt;/p&gt;
&lt;p&gt;寫成程式碼如下。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，使用charAt()來取得特定index的字元，&lt;br&gt;
並分別設定l跟r變數來計算。(要設成同一個cnt變數也行，自己歸零即可)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/b56b4a7c4847de705aa2b37a7173e5bd.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，這邊使用三元運算子處理。&lt;br&gt;
此外，如果不想用index一個一個數的話，&lt;br&gt;
用for c in s以及for c in reversed(s)也可以。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/86b1232ac8258f63c1e8f84b171f8da4.js"&gt;&lt;/script&gt;
&lt;p&gt;讀者可能會留意到註解裡有附註了&lt;a class="link" href="https://leetcode.com/problems/valid-parenthesis-string/discuss/107570/JavaC%2B%2BPython-One-Pass-Count-the-Open-Parenthesis" target="_blank" rel="noopener"
&gt;&lt;strong&gt;lee215的one pass解法&lt;/strong&gt; &lt;/a&gt;，&lt;br&gt;
有興趣的可以再深入了解。具體的思路是記錄從左至右途中，&lt;br&gt;
我們現在需要等待多少右括號來將一組括號完整；&lt;br&gt;
&lt;strong&gt;cmax&lt;/strong&gt; 是&lt;strong&gt;將所有碰到的*都當作是左括號&lt;/strong&gt; 處理，&lt;br&gt;
(也就是最大&lt;strong&gt;可能&lt;/strong&gt; 會產生尚未配對的左括號數量)&lt;br&gt;
而&lt;strong&gt;cmin&lt;/strong&gt; 是&lt;strong&gt;中間能消去配對的狀況就消去&lt;/strong&gt; 。&lt;br&gt;
(也就是最少&lt;strong&gt;一定&lt;/strong&gt; 要被配對完成的左括號數量)&lt;br&gt;
按這個條件的話，cmax必然要一直&amp;gt;=0，&lt;br&gt;
且cmin再結尾時要剛好是0才可以。&lt;/p&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(n)/O(1)，n為字串長度，空間不論是哪種方式都只需常數大小)&lt;/p&gt;
&lt;p&gt;「如果不管空間複雜度，你能使用stack來解這題嗎？」&lt;br&gt;
(可以做配對然後將成對的括號吐掉，&lt;br&gt;
具體可以參考以下幾個discussion的解法。&lt;br&gt;
Java: &lt;a class="link" href="https://leetcode.com/problems/valid-parenthesis-string/discuss/107572/Java-using-2-stacks.-O%28n%29-space-and-time-complexity." target="_blank" rel="noopener"
&gt;https://leetcode.com/problems/valid-parenthesis-string/discuss/107572/Java-using-2-stacks.-O(n)-space-and-time-complexity.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Python: &lt;a class="link" href="https://leetcode.com/problems/valid-parenthesis-string/discuss/145228/python-using-stack-20ms-beats-100-probably-the-easiest-solution" target="_blank" rel="noopener"
&gt;https://leetcode.com/problems/valid-parenthesis-string/discuss/145228/python-using-stack-20ms-beats-100-probably-the-easiest-solution&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;感謝大家對這系列文章的支持！這邊跟大家自我工商一下：&lt;/p&gt;
&lt;p&gt;筆者開設的系列同名線上課程：&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜基礎篇」已經上線啦！&lt;/strong&gt; 在這堂課中，你將學會利用十種演算法/資料結構來優化解題過程，&lt;br&gt;
並實際完整練習&lt;strong&gt;20題&lt;/strong&gt; 精選考古題，&lt;br&gt;
進而逐漸提升到不需提示也可以突破白板題，取得工作門票！&lt;br&gt;
&lt;strong&gt;Medium優惠(最後一波早鳥優惠了，不確定調回原價是什麼時候)：&lt;/strong&gt; &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 85 String (3)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-85-string-3/</link><pubDate>Thu, 30 Jan 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-85-string-3/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 85 String (3)" /&gt;&lt;p&gt;&lt;strong&gt;1332. Remove Palindromic Subsequences (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a string &lt;code&gt;s&lt;/code&gt; consisting only of letters &lt;code&gt;'a'&lt;/code&gt; and &lt;code&gt;'b'&lt;/code&gt;. In a single step you can remove one palindromic &lt;strong&gt;subsequence&lt;/strong&gt; from &lt;code&gt;s&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Return the minimum number of steps to make the given string empty.&lt;/p&gt;
&lt;p&gt;A string is a subsequence of a given string, if it is generated by deleting some characters of a given string without changing its order.&lt;/p&gt;
&lt;p&gt;A string is called palindrome if is one that reads the same backward as well as forward.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;ababa&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: String is already palindrome
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;abb&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: &amp;#34;abb&amp;#34; -&amp;gt; &amp;#34;bb&amp;#34; -&amp;gt; &amp;#34;&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Remove palindromic subsequence &amp;#34;a&amp;#34; then &amp;#34;bb&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;baabb&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: &amp;#34;baabb&amp;#34; -&amp;gt; &amp;#34;b&amp;#34; -&amp;gt; &amp;#34;&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Remove palindromic subsequence &amp;#34;baab&amp;#34; then &amp;#34;b&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-4"&gt;Example 4
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: s = &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= s.length &amp;lt;= 1000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; only consists of letters &amp;lsquo;a&amp;rsquo; and &amp;lsquo;b&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個字串，當中僅由&amp;rsquo;a&amp;rsquo;或&amp;rsquo;b&amp;rsquo;的字母所構成，每次你可以從中移除一個palindrome subsequence. 試回傳將該字串刪成空字串所需的最小步數。&lt;/p&gt;
&lt;p&gt;我們先前有講過subsequence的定義，可以參照之前的&lt;a class="link" href="https://medium.com/@desolution/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-78-two-pointer-4-binary-search-5-49e21e35d2a5" target="_blank" rel="noopener"
&gt;&lt;strong&gt;題目&lt;/strong&gt; &lt;/a&gt;。&lt;br&gt;
所以每次要移除掉一個subsequence且必須符合palindrome的條件，&lt;br&gt;
乍看之下似乎不容易。&lt;br&gt;
但選這題的目的就是要告訴大家，有時候事情並沒有想像中那麼複雜，&lt;br&gt;
靜下心來好好推敲，可能可以找到適合的規律，&lt;br&gt;
不要急著找通解，先試著去&lt;strong&gt;用上所有已知的條件&lt;/strong&gt; 看看才對！&lt;/p&gt;
&lt;p&gt;我們知道subsequence就是按照排列的先後順序取就可以了，&lt;br&gt;
但&lt;strong&gt;palindrome(回文)&lt;/strong&gt; 則必須取出來從頭到尾和從尾到頭一致才行。&lt;/p&gt;
&lt;p&gt;我們先考慮最簡單的部分，再慢慢往下推。&lt;br&gt;
&lt;strong&gt;1. 當字串是空白的時候：&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;不需操作&lt;/strong&gt; 即可達到條件，&lt;strong&gt;所以總step為0。&lt;br&gt;
2. 當字串本身就是palindrome：&lt;br&gt;
把整個字串做為subsequence移除，所以總step為1。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;接下來是最重要的部分，&lt;br&gt;
如果字串本身不是palindrome的話，&lt;br&gt;
要怎麼樣才會移除一個palindrome sequence後，&lt;br&gt;
可以用最小步數化簡呢？&lt;br&gt;
&lt;strong&gt;由於s僅僅由’a’和’b’所組成&lt;/strong&gt; ，&lt;br&gt;
所以我們可以考慮&lt;strong&gt;直接移去全部的&amp;rsquo;a&amp;rsquo;或全部的&amp;rsquo;b&amp;rsquo;，&lt;br&gt;
由於全部都是&amp;rsquo;a&amp;rsquo;或全部都是&amp;rsquo;b&amp;rsquo;也是一種palindrome，&lt;br&gt;
所以符合前面移除的規則；&lt;br&gt;
而剩下來的就全部都是另外一種字元，&lt;br&gt;
同樣也構成palindrome。&lt;br&gt;
因此，最多只要2個step，就能全數移完。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(想一下，如果今天是有N種不同的字元構成s，&lt;br&gt;
最多就會需要N個step，但這只是上限而已，而不是minimum steps。)&lt;/p&gt;
&lt;p&gt;有興趣寫更細的話，可以用two pointer來寫這題的檢查palindrome的部分，&lt;br&gt;
這裡就直接用簡單的操作處理。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，操作&lt;strong&gt;reverse&lt;/strong&gt; 要使用&lt;strong&gt;StringBuilder&lt;/strong&gt; 來處理，&lt;br&gt;
處理完以後，再轉回String。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/05c2e5731e195ddd44754fd326e3e8cc.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分更精簡，使用**[::-1]** 即可表達&lt;strong&gt;從尾到頭&lt;/strong&gt; 的部分。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/1739bde8255945c392e5c87dec946573.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(N)，若願意一個一個字元比較的話，&lt;br&gt;
空間複雜度也可以降到O(1)，也就是用簡單的two pointer處理即可)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;感謝大家對這系列文章的支持！這邊跟大家自我工商一下：&lt;/p&gt;
&lt;p&gt;筆者開設的系列同名線上課程：&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜基礎篇」已經上線啦！&lt;/strong&gt; 在這堂課中，你將學會利用十種演算法/資料結構來優化解題過程，&lt;br&gt;
並實際完整練習&lt;strong&gt;20題&lt;/strong&gt; 精選考古題，&lt;br&gt;
進而逐漸提升到不需提示也可以突破白板題，取得工作門票！&lt;br&gt;
&lt;strong&gt;Medium優惠(最後一波早鳥優惠了，不確定調回原價是什麼時候)：&lt;/strong&gt; &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 77 String (2)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-77-string-2/</link><pubDate>Tue, 24 Dec 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-77-string-2/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 77 String (2)" /&gt;&lt;p&gt;&lt;strong&gt;1071. Greatest Common Divisor of Strings (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;For strings &lt;code&gt;S&lt;/code&gt; and &lt;code&gt;T&lt;/code&gt;, we say &amp;ldquo;&lt;code&gt;T&lt;/code&gt; divides &lt;code&gt;S&lt;/code&gt;&amp;rdquo; if and only if &lt;code&gt;S = T + ... + T&lt;/code&gt; (&lt;code&gt;T&lt;/code&gt; concatenated with itself 1 or more times)&lt;/p&gt;
&lt;p&gt;Return the largest string &lt;code&gt;X&lt;/code&gt; such that &lt;code&gt;X&lt;/code&gt; divides str1 and &lt;code&gt;X&lt;/code&gt; divides str2.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: str1 = &amp;#34;ABCABC&amp;#34;, str2 = &amp;#34;ABC&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;ABC&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: str1 = &amp;#34;ABABAB&amp;#34;, str2 = &amp;#34;ABAB&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;AB&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: str1 = &amp;#34;LEET&amp;#34;, str2 = &amp;#34;CODE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= str1.length &amp;lt;= 1000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= str2.length &amp;lt;= 1000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;str1[i]&lt;/code&gt; and &lt;code&gt;str2[i]&lt;/code&gt; are English uppercase letters.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定兩字串，找出能「除盡」這兩個字串的最長字串X。&lt;br&gt;
題目已經給定的非常明顯了就是在求gcd(最大公因數)，&lt;br&gt;
因此，拿出小學就教過的輾轉相除法即可。&lt;br&gt;
(要看起來厲害一點的話，也可以叫歐幾里得算法Euclidean algorithm)&lt;/p&gt;
&lt;p&gt;輾轉相除法告訴我們說，兩個數的最大公因數，&lt;br&gt;
就是不斷將大的除以小的，取出餘數替代之，直到能夠整除為止。&lt;br&gt;
於是這邊變成字串時，我們的除就會比較麻煩一點。&lt;br&gt;
為求簡單起見，我們可以&lt;strong&gt;固定將第一個字串選擇放比較長的&lt;/strong&gt; ，&lt;br&gt;
如果&lt;strong&gt;發現相反&lt;/strong&gt; 的話，則將&lt;strong&gt;兩者進行對調&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;所以就可以分成以下的步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;取兩字串長l1, l2，若&lt;strong&gt;l1 &amp;lt; l2&lt;/strong&gt; 則呼叫遞迴&lt;strong&gt;將str1, str2交換&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;若&lt;strong&gt;str1和str2完全一樣，則回傳str1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;若&lt;strong&gt;str1的前面的部分&lt;/strong&gt; 和&lt;strong&gt;str2&lt;/strong&gt; 一樣，則將&lt;strong&gt;str1扣除掉該部份&lt;/strong&gt; 以後，&lt;br&gt;
呼叫遞迴傳入繼續計算。&lt;br&gt;
(因為我們&lt;strong&gt;操作字串的除只能一組一組扣掉&lt;/strong&gt; )&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;否則就回傳空字串&lt;/strong&gt; (因為不一樣的話代表完全沒有共同的字串，&lt;br&gt;
跟數字的最大公因數是1概念一樣)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，字串相等請使用equals來比較，&lt;br&gt;
而前面的部分一樣可以用startsWith函式，&lt;br&gt;
並留意空字串要用雙引號，不能用單引號(因為單引號是char)。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/f9c0aac5ec9fcf7cbfe93a3080581a98.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，使用==和串列取值的方式，&lt;br&gt;
可以簡單達成我們所需要的操作。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/e10ef7464eda8e4eba004dcbf086cde7.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(l1+l2)/O(l1+l2)，由於每階段會固定消去最小單位的長度，&lt;br&gt;
所以最差的狀況就是全部都消去，也就做了兩字串長度的消去的動作，&lt;br&gt;
但中間未考慮比較是否相等的狀況。&lt;br&gt;
空間複雜度的部分，&lt;br&gt;
Java的substring和Python的切list的方式都會產生新的單位，&lt;br&gt;
理論上仍然最少會佔用到完整的l1+l2單位空間)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;感謝大家對這系列文章的支持！這邊跟大家自我工商一下：&lt;/p&gt;
&lt;p&gt;筆者開設的系列同名線上課程：&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜基礎篇」已經上線啦！&lt;/strong&gt; 在這堂課中，你將學會利用十種演算法/資料結構來優化解題過程，&lt;br&gt;
並實際完整練習&lt;strong&gt;20題&lt;/strong&gt; 精選考古題，&lt;br&gt;
進而逐漸提升到不需提示也可以突破白板題，取得工作門票！&lt;br&gt;
&lt;strong&gt;Medium優惠(額滿即截止)：&lt;/strong&gt; &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=VEQZV7E" target="_blank" rel="noopener"
&gt;&lt;strong&gt;https://hiskio.com/courses/319?promo_code=VEQZV7E&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>