<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Newton's Method on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/newtons-method/</link><description>Recent content in Newton's Method on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Mon, 01 Feb 2021 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/newtons-method/index.xml" rel="self" type="application/rss+xml"/><item><title>從LeetCode學演算法 - 112 Binary Search (6) / Newton’s Method</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-112-binary-search-6-newton-s-method/</link><pubDate>Mon, 01 Feb 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-112-binary-search-6-newton-s-method/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 112 Binary Search (6) / Newton’s Method" /&gt;&lt;p&gt;&lt;strong&gt;0367. Valid Perfect Square (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;目前&lt;strong&gt;0元挑戰賽&lt;/strong&gt; 的活動已經開始囉！&lt;br&gt;
只要&lt;strong&gt;修課後三個月內完課且成功錄取新工作並撰寫心得，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;課程就會全額退費喲！請使用下面連結看更詳細的規則說明：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;同時，還有限時更便宜的套組3490 (再便宜500呦！限額10名！)&lt;br&gt;
新年限量組合🎁 零元求職挑戰賽 Python 組｜從 LeetCode 學演算法&lt;/strong&gt;&lt;a class="link" href="https://hiskio.com/packages/ZXwe2p9yv" target="_blank" rel="noopener"
&gt;https://hiskio.com/packages/ZXwe2p9yv&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;零元求職挑戰賽 Python 組｜從 LeetCode 學演算法 + 面試成功指南&lt;/strong&gt; &lt;a class="link" href="https://bit.ly/zeroclg?fbclid=IwAR0cGOc6L5R4j26i6BqncG0m1tPPPx5-Z1M0vAOzJpnwUrByX3q-gWE1Sfw" target="_blank" rel="noopener"
&gt;http://bit.ly/zeroclg&lt;/a&gt;&lt;/p&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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a &lt;strong&gt;positive&lt;/strong&gt; integer &lt;em&gt;num&lt;/em&gt;, write a function which returns True if &lt;em&gt;num&lt;/em&gt; is a perfect square else False.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow up:&lt;/strong&gt; ** Do not** use any built-in library function such as &lt;code&gt;sqrt&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;/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: num = 16
&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: num = 14
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: false
&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;= num &amp;lt;= 2^31 - 1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個正整數num，試檢驗num是否為完全平方數(也就是可以分解成兩個完全相等的數相乘)。&lt;br&gt;
請不要使用內建的sqrt或類似的函式。&lt;/p&gt;
&lt;p&gt;雖然被封印了平方根函數，但已經看到標題的讀者應該不難猜想到，&lt;br&gt;
我們可以運用一般的二分逼近法，&lt;br&gt;
去將目標(我們先稱之為x)的範圍縮小。&lt;br&gt;
當找到 x² 和num相等時，就表示num是完全平方數(回傳True)，&lt;br&gt;
否則一路找到兩個邊界交叉時，表示num不存在整數平方根，&lt;br&gt;
我們就可以回傳False。&lt;/p&gt;
&lt;p&gt;那麼，有沒有再更厲害一點的方法呢？&lt;br&gt;
這邊來介紹一下一個著名的方法，名為牛頓法(Newton’s Method)。&lt;br&gt;
我們在求x² = num當中的x，(下面方便起見，將num寫成n)&lt;br&gt;
其實相當於求 y = f(x) = x² - n在y = 0時的正根。&lt;br&gt;
假定r是這個根，我們先取一個任意一個比較大的值x0，&lt;br&gt;
那麼它對應到的座標應該是(x0, f(x0))。&lt;br&gt;
對於這個點做曲線的切線的話，應該可以得到切線方程式：&lt;br&gt;
&lt;strong&gt;y = f(x0) + f&amp;rsquo;(x0) (x-x0) &lt;br&gt;
也就是y = ax +b嘛! a就是在x0上的切線斜率，&lt;br&gt;
而x代入x0的話可以驗證y = f(x0)，&lt;br&gt;
所以這個方程式可以表達該切線沒錯。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我們將這個切線叫做L，&lt;br&gt;
那麼L和x軸的交點的x座標，應該就和r更近囉！&lt;br&gt;
(想像一下拋物線的斜度會越來越平，所以切線和x軸的交點，&lt;br&gt;
比起拋物線和x軸的交點來說應該會大一點)&lt;br&gt;
我們將後面和x軸的交點位置叫做&lt;strong&gt;x1&lt;/strong&gt; ，&lt;br&gt;
那麼就可以計算其&lt;strong&gt;斜率為 f(x0) / (x0-x1) = (x0²-n)/(x0-x1)&lt;/strong&gt; ，&lt;br&gt;
同時也等於&lt;strong&gt;f(x)的導數(就是對其微分)f’(x) = 2x&lt;/strong&gt; 。&lt;br&gt;
因此，2x0 = (x0²-n)/(x0-x1) -&amp;gt; 2x0(x0-x1) = x0²-n&lt;br&gt;
繼續化簡：&lt;br&gt;
-&amp;gt; 2x0²-2x0x1=x0²-n&lt;br&gt;
-&amp;gt; x0²+n = 2x0x1&lt;br&gt;
-&amp;gt; &lt;strong&gt;x1 = (x0 + n/x0) / 2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-112-binary-search-6-newton-s-method/image-001.png"
width="800"
height="734"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-112-binary-search-6-newton-s-method/image-001_hu_21abf510b9f24ccc.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-112-binary-search-6-newton-s-method/image-001_hu_c3978e53d3d16c5c.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="108"
data-flex-basis="261px"
&gt;&lt;/p&gt;
&lt;p&gt;每次取得一個更接近的x來逼近r的位置&lt;/p&gt;
&lt;p&gt;我們可以再用這個x1再取得在f(x)上的點，接下來再畫切線，&lt;br&gt;
重復上面的動作。&lt;br&gt;
當我們每次用前面這個算式迭代，就可以取得一個新的x，&lt;br&gt;
理論上它會更接近於r。(x1, x2, x3, …)&lt;br&gt;
由於要取的是整數，所以我們在計算的時候，&lt;br&gt;
就將所有的算式中的除法都取整數，&lt;br&gt;
這樣算出來的狀況，就會變得有機會更小。&lt;br&gt;
所以在運用到實際的計算時，&lt;br&gt;
我們可以設定一個迴圈，將x直接先定為num，&lt;br&gt;
當x² &amp;gt; num時，就持續迴圈，&lt;br&gt;
那麼在x持續縮小的狀況下，&lt;br&gt;
最終要嘛縮小到剛好得到一個正整數的平方根，&lt;br&gt;
要嘛就是x²已經小於num了，我們就不用繼續往下做啦！&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java-java的部分請留意到大小問題我們應該要使用long來宣告變數"&gt;Java Java的部分，請留意到大小問題，我們應該要使用long來宣告變數。
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/22935065681018fa2120af827ebe5788.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python部分則請不要忘記整數除法是”//”。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/a9273b962c9c694532f561c075e4a097.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(時間複雜度難以界定，最差應該是O(num)，(但二分法也是)&lt;br&gt;
平均應該優於O(log(num))，這可能也取決於初始值的取法；&lt;br&gt;
空間複雜度則為O(1))&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;相似及延伸：&lt;br&gt;
本題還有其他的解法可以參考以下連結&lt;/strong&gt;&lt;a class="link" href="https://leetcode.com/problems/valid-perfect-square/discuss/130010/Python-4-Methods-with-time-testing" target="_blank" rel="noopener"
&gt;https://leetcode.com/problems/valid-perfect-square/discuss/130010/Python-4-Methods-with-time-testing&lt;/a&gt;&lt;/p&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></channel></rss>