1、遞歸和尾遞歸優化
1)遞歸
遞歸:把一個大型複雜的問題層層轉化爲一個與原問題相似的規模較小的問題來。只需要少量的程序就可描述出解題過程所需要的多次重複計算
fun main(args: Array<String>) {
//求5的階乘 5*4*3*2*1
// println(fact(5))
println(fibonacci(6))
}
/**
* 求n的階乘
*/
fun fact(n: Int): Int {
if (n == 1) {
return 1
} else {
return n * fact(n - 1)
}
}
//斐波拉切數列 1 1 2 3 5 8 13 21
fun fibonacci(n: Int): Int {
return if (n == 1 || n == 2) {
1
} else {
fibonacci(n - 2) + fibonacci(n - 1)
}
}
2)尾遞歸優化
尾遞歸:函數在調用自己之後沒有執行其他任何操作的就是尾遞歸;
使用遞歸方法,遞歸容易報內存溢出, 解決就是使用尾遞歸。
步驟:
第一步:需要將遞歸轉換爲尾遞歸
第二步:加上tailrec
原理:還是迭代
fun main(args: Array<String>) {
//需求:求1到n的數據和 1到10
println(sum(100000))//使用遞歸內存溢出
println("${2%5}")
}
tailrec fun sum(n: Int, result: Int = 0): Int {
if (n == 1) {
return result + 1
} else {
return sum(n - 1, result + n)
}
}
2、遞歸和迭代
遞歸和迭代的對比
常見問題:通過迭代好遞歸都可以解決,複雜的問題用遞歸更容易實現
遞歸和迭代有什麼優缺點?
遞歸:邏輯比較簡單 容易實現 缺點:容易佔內存溢出
迭代:優點:內存開銷小 缺點:抽象出數學模型
fun main(args: Array<String>) {
//需求:求1到n的數據和 1到10
// println(sum(100000))//使用遞歸內存溢出
println(sum1(100000))//使用迭代沒問題
}
/**
* 求和使用迭代的方法
*/
fun sum1(n: Int): Int {
var result = 0
var copyN: Int = n
while (copyN > 0) {
result += copyN
copyN--
}
return result
}
/**
* 使用遞歸方法
*/
fun sum(n: Int): Int {
if (n == 1) {
return 1
} else {
return n + sum(n - 1)
}
}