Leetcode Note: Go - Climbing Stairs
Climbing Stairs - LeetCode
https://leetcode.com/problems/climbing-stairs/
- Go 言語で取り組んだメモ
所感
- 全くわからん
- 偶数か奇数か判定して、使用可能な 2 を 1, 1 に置き換えられるパターン数をカウントする?
- わからん・・・
実装準備
func climbStairs(n int) int {
return 0
}
func main() {
n := 3
fmt.Println(climbStairs(3))
}
Solutions
Python/JS/Go/C++ O(n) DP // Fibonacci [w/ Hint ] - LeetCode Discuss
https://leetcode.com/problems/climbing-stairs/discuss/628462/PythonJSGoC%2B%2B-O(n)-DP-Fibonacci-w-Hint
Golang 0ms DP - LeetCode Discuss
https://leetcode.com/problems/climbing-stairs/discuss/25379/Golang-0ms-DP
go solution - LeetCode Discuss
https://leetcode.com/problems/climbing-stairs/discuss/1567398/go-solution
- Fibonacci を Dynamic Programming で解くのがメジャーな解法っぽい
回答
Python/JS/Go/C++ O(n) DP // Fibonacci [w/ Hint ] - LeetCode Discuss
https://leetcode.com/problems/climbing-stairs/discuss/628462/PythonJSGoC%2B%2B-O(n)-DP-Fibonacci-w-Hint
func climbStairs(n int) int {
// key: stair i
// value: method count of climbing to stair i
memo := make(map[int]int)
// initialization on base case
memo[0] = 1
memo[1] = 1
// define inenr function: climb
var climb func(int) int
climb = func(i int) int {
if i <= 1 {
// base case
return memo[i]
} else if val, exist := memo[i]; exist {
// climb(i) has been computed before, directly look-up memo
return val
} else {
// general cases
memo[i] = climb(i-1) + climb(i-2)
return memo[i]
}
}
return climb(n)
}
- LeetCode の Discuss 投稿は、別に 1つ の投稿に対して 1つ の言語解説じゃなくても良いんだな・・・
- むしろ色んな言語での解法も記載すると、 View 数も評価も良いっぽい
- 解法
- フィボナッチ数と再帰を使う
- Climbing Stairs は
Method to level n = Method to level (n-1) + Method to level (n-2)
と表現できる - つまり
f( n ) = f( n - 1 ) + f( n - 2 )
- これを Top Down DP で解く
- Go での実装
- 数値を保持するための変数として memo を定義
memo := make(map[int]int)
memo[0] = 1
memo[1] = 1
- 再帰関数である climb を実装
- 引数で受け取った i が 1 以下なら
return memo[i]
- i が 2 以上、かつ、
memo[i]
に値があればreturn val
実質return memo[i]
- それら以外であれば
memo[i] = climb(i-1) + climb(i-2)
してreturn memo[i]
- これが再帰呼び出しになる
- 引数で受け取った i が 1 以下なら
- climb に n を指定して呼び出す
- 数値を保持するための変数として memo を定義
climb が呼び出された際に i を出力するよう修正した実行例
n = 1, return 1
climb i: 1
n = 2, return 2
climb i: 2
climb i: 1
climb i: 0
n = 3, return 3
climb i: 3
climb i: 2
climb i: 1
climb i: 0
climb i: 1
n = 4, return 5
climb i: 4
climb i: 3
climb i: 2
climb i: 1
climb i: 0
climb i: 1
climb i: 2
n = 5, return 8
climb i: 5
climb i: 4
climb i: 3
climb i: 2
climb i: 1
climb i: 0
climb i: 1
climb i: 2
climb i: 3
- 解説を見たものの腹落ちした感じはせず・・・
- DP をもっと理解する必要がありそう