分治法的含义
字面上的解释是
分而治之
,就是把一个复杂的问题分成两个或更多的相同或相似的子问题。
直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
分治法一般使用递归来求问题的解。
递归
递归就是一个函数自已调用自已本身
我们先看这样一个问题
给定一个数,求解这个数的阶乘
现在我们用递归来求解这个问题
package main
import "fmt"
func Rescuvie(n int) int{
//0的阶乘为1
if n == 0 {
return 1
}
return n * Rescuvie(n - 1)
}
func main(){
var n int
fmt.Scan(&n)
fmt.Println(Rescuvie(n))
}
这个过程就是这样的
1.
Rescuvie(5)
2.5 * Rescuvie(4)
3.5 * 4 * Rescuvie(3)
4.5 * 4 * 3 * Rescuvie(2)
5.5 * 4 * 3 * 2 * Rescuvie(1)
6.5 * 4 * 3 * 2 * 1
7.5 * 4 * 3 * 2
8.5 * 4 * 6
9.5 * 24
120
我们随着数据的增大我们我们每一行的长度也会增大,栈在不断的运行与恢复,数据越大运行越慢
尾递归
所以我们采用另一种叫尾递归
尾部递归是指递归函数在调用自身后直接传回其值,而不对其再加运算,效率将会极大的提高
package main
import "fmt"
func Recuvie(n int , a int) int {
if n == 1 {
return a
}
return Recuvie(n - 1 , a * n)
}
func main() {
var n int
fmt.Scan(&n)
fmt.Println(Recuvie(n,1))
}
输入5
其过程为:
Rescuviel(5, 1)
Rescuvie(4, 15)=Rescuvie(4, 5)
Rescuvie(3, 54)=Rescuvie(3, 20)
Rescuvie(2, 203)=Rescuvie(2, 60)
Rescuvie(1, 602)=Rescuvie(1, 120)
120
斐波那契数列尾递归求解
package main
import "fmt"
func F(n int, a1, a2 int) int {
if n == 0 {
return a1
}
return F(n-1, a2, a1+a2)
}
func main() {
var n int
fmt.Scan(&n)
fmt.Println(F(n,1,1))
}
输入3
其过程为
F(3,1,1)
F(2,1,2)
F(1,2,3)
F(0,3,5)
二分查找
在leetcode上对应的题
二分查找的思路
1.找出一个数字a
2.将中位数与a比较
如果大于a向中位数左边找
如果小于a向中位数右边找
func search(nums []int, target int) int {
var left,right int = 0,len(nums) - 1
for {
if left > right {
return -1
}
mid := (left + right) >> 1
if nums[mid] > target {
right = mid - 1
} else if nums[mid] < target {
left = mid + 1
} else {
return mid
}
}
}