對于我自己的開發,我嘗試撰寫在 Web/books/Udemy 上找到的演算法。我遇到的最有趣的一個是尋找Widest Path without Trees的那個。簡而言之:0 to N-1森林中有 N 棵樹(編號從 開始)。第 K 棵樹位于坐標(X[K], Y[K])。目標是建立盡可能寬的垂直路徑,這樣上面就沒有樹。
鏈接的預期結果應該是:
Write a function:
def solution(X, Y)
that, given two arrays X and Y consisting of N integers each, denoting the positions of trees, returns the widest possible path that can be built.
Example 3:
Input: X = [4, 1, 5, 4], Y=[4, 5, 1, 3]
Output: 3
如何做到這一點?
[編輯]
到目前為止,我所做的是對 X 陣列進行排序(我猜 Y 無關緊要(?))并遍歷每個元素以找到這兩者之間的長度:
> x
=> [4, 1, 5, 4]
> y
=> [4, 5, 1, 3]
> x.sort.map.with_index { |e, i| x[i 1] - x[i] unless x[i 1].nil?}.compact.max
=> 4
我不知道任務內部是否有錯誤,或者我不明白某些內容,但我的代碼產生了 4 而不是 3。
uj5u.com熱心網友回復:
找出代碼出了什么問題的一種方法是逐步完成它的作業。
您可以使用除錯器來執行此操作,在每個步驟中檢查程式的狀態,您可以通過在每個步驟中列印出程式的狀態以更手動的方式執行此操作,或者您可以簡單地使用筆和紙來完成。
您要做的第一件事是創建一個新陣列,它是x使用該Array#sort方法的排序版本:
sorted_x = x.sort
#=> [1, 4, 4, 5]
接下來你要做的是為所述排序陣列Enumerator的方法創建一個:Array#map
map_enum = sorted_x.map
map_enum.to_a
#=> [1, 4, 4, 5]
接下來,您使用Enumerator#with_index將每個元素與其索引配對:
map_with_index_enum = map_enum.with_index
map_with_index_enum.to_a
#=> [[1, 0], [4, 1], [4, 2], [5, 3]]
在傳遞給 的塊中Enumerator#with_index,使用塊引數系結的陣列解構特性將元素系結到e并將索引系結到i,這為塊的每次迭代提供了以下系結:
| 迭代 | e |
i |
|---|---|---|
| 1 | 1 |
0 |
| 2 | 4 |
1 |
| 3 | 4 |
2 |
| 4 | 5 |
3 |
但是,在塊內你永遠不會e在任何地方使用,所以它實際上是完全不相關的:
| 迭代 | i |
|---|---|
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
實際上,您在塊中所做的所有事情都是從0到計數x.size - 1,或者換句話說,遍歷 的所有索引x。您永遠不會使用排序陣列的元素sorted_x,因此整個歌曲和舞蹈與排序x和映射它與索引是多余的。你可以使用類似的東西
x.each_index.map {|i| x[i 1] - x[i] unless x[i 1].nil? }.compact.max
或者
x.each_index.filter_map {|i| x[i 1] - x[i] unless x[i 1].nil? }.max
反而。
但這只是一個旁注,讓我們一步一步地完成這個塊:
| 迭代 | i |
x[i 1] |
x[i] |
結果 |
|---|---|---|---|---|
| 1 | 0 |
x[1] == 1 |
x[0] == 4 |
1 - 4 == -3 |
| 2 | 1 |
x[2] == 5 |
x[1] == 1 |
5 - 1 == 4 |
| 3 | 2 |
x[3] == 4 |
x[2] == 5 |
4 - 5 == -1 |
| 4 | 3 |
x[4] == nil |
x[3] == 4 |
nil |
或者,簡而言之,迭代的結果就是陣列
result = [-3, 4, -1, nil]
下一步,您使用Array#compact洗掉所有nil元素,這會導致
compacted_result = result.compact
#=> [-3, 4, -1]
最后,您Array#max可以找到壓縮結果的最大元素:
compacted_result.max
#=> 4
您的演算法所做的只是計算相鄰元素之間的差異x并找到最大值,這可以用 Ruby 表示,如下所示:
x.each_cons(2).map { |a, b| b - a }.max
#=> 4
實際上,我們只對相鄰元素之間的絕對差異感興趣,所以我們應該Numeric#abs在塊內部使用:
x.each_cons(2).map { |a, b| (b - a).abs }.max
#=> 4
或者,將結果映射到絕對值:
x.each_cons(2).map { |a, b| b - a }.map(&:abs).max
#=> 4
但是,如您所見,這不會改變結果。
主要問題是相鄰元素之間沒有關系,因此取它們的差異沒有意義。但是,當我們對陣列進行排序時,排序后的陣列中的相鄰元素實際上代表了森林中的相鄰樹,突然之間,取它們的差值確實有意義:
x.sort.each_cons(2).map { |a, b| b - a }.max
#=> 3
請注意,我們不再需要采用絕對差值,因為陣列處于非遞減順序這一事實保證了相鄰元素的差值始終為非負數。
因此,這就是您的代碼的問題:您正在獲取 中相鄰元素的差異x,但在您嘗試解決的實際問題中,這些相鄰元素實際上彼此無關。
您對陣列進行排序的想法是正確的,但您從未在任何地方使用過排序的陣列。
但是,真正的問題是您沒有撰寫 Ruby 代碼。與大多數現代主流編程語言一樣,Ruby 有一個強大的集合庫,其中包含各種更高級別的迭代器,例如map、reduce、select以及許多更多的 。在 Ruby 中,每當你不得不擺弄陣列索引、回圈,甚至是each它的朋友時,這肯定表明你做錯了。
在擺弄索引的所有程序中,您忘記了您實際上從未在任何地方使用排序陣列的事實。如果您以更 Ruby 的風格撰寫代碼,這會更加明顯,例如:
x.sort.each_cons(2).map { |a, b| b - a }.max
# vs.
x.each_cons(2).map { |a, b| b - a }.max
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/495314.html
上一篇:僅列出的軌道ID與當前用戶相同
