算法-分治法
本章是算法-分治法的总结,主要讲解分治法的思想,然后就课堂上的几个例子用Golang实现。
分治法的思想
Divide and Conquer
three step:
1)divide : one bigger to one or more subproblem
2)conquer: solve each subproblem recursively
3)combine
merge sort
归并算法的实现,其递归的式子为 T ( n ) = 2 ∗ T ( n / 2 ) + Θ ( n ) T(n) = 2*T(n/2) + \Theta(n) T(n)=2∗T(n/2)+Θ(n) 这个式子满足case2的情况,即 f ( n ) = Θ ( n log 2 2 ∗ l g n 0 ) f(n)=\Theta(n^{\log_22}*{lgn}^0) f(n)=Θ(nlog22∗lgn0) and the answer is T ( n ) = n l g n T(n)=nlgn T(n)=nlgn
binary search
func binarySearch(src []int, left, right, objNum int){
if left == right{
if src[left] == objNum{
fmt.Println(left)
return
}else {
fmt.Println("can't find num")
return
}
}
mid := (left+right)/2
if src[mid] > objNum{
binarySearch(src, left, mid-1, objNum)
}else if src[mid] < objNum{
binarySearch(src, mid+1, right, objNum)
}else {
fmt.Println(mid)
return
}
}
func BinarySearch(src []int, objNum int){
if len(src) == 0 {
return
}
binarySearch(src, 0, len(src)-1, objNum)
}
其递归式是 T ( n ) = T ( n / 2 ) + Θ ( 1 ) T(n)= T(n/2)+\Theta(1) T(n)=T(n/2)+Θ(1)满足case2, T ( n ) = l g n T(n)=lgn T(n)=lgn
powering a number
func PowerNum(num, cnt int) int{
if cnt == 1{
return num
}
if cnt%2 == 0{
temp := PowerNum(num, cnt/2)
return temp*temp
}else {
temp := PowerNum(num, (cnt-1)/2)
return temp*temp*num
}
}
其递归式是 T ( n ) = T ( n / 2 ) + Θ ( 1 ) T(n)= T(n/2)+\Theta(1) T(n)=T(n/2)+Θ(1)满足case2, T ( n ) = l g n T(n)=lgn T(n)=lgn
Fibonacci numbers
type operCube [2][2]int
var srcMatrix operCube = operCube{{1,1},{1,0}}
func plusOfMatrix(A, B operCube) (C operCube){
for i := 0; i < 2; i++{
a := A[i]
for k := 0; k < 2; k++{
b := [2]int{B[k][0], B[k][1]}
C[i][k] = plusOfVector(a, b)
}
}
return
}
func plusOfVector(a, b [2]int) (ans int){
for i := 0; i<2; i++{
ans += a[i]*b[i]
}
return
}
func fibonacci2(cnt int) operCube {
if cnt == 1 || cnt == 0{
return srcMatrix
}
if cnt%2 == 0{
temp := fibonacci2(cnt/2)
return plusOfMatrix(temp,temp)
}else {
temp := fibonacci2((cnt-1)/2)
return plusOfMatrix(plusOfMatrix(temp,temp),srcMatrix)
}
}
func Fibonacci2(cnt int) int{
if cnt == 0 {
return fibonacci2(cnt)[1][1]
}else {
return fibonacci2(cnt)[0][1]
}
}
func Fibonacci1(step int) int {
if step == 0 {return 0} else if step == 1{return 1}
return Fibonacci1(step-1)+Fibonacci1(step-2)
}
这是Fibonacci数列的两种解法,一种的时间复杂度很高指数增长,利用数列的特性来解决的算法可以将时间复杂度提升到 l g n lgn lgn
matrix manipulation
这个讲解的过程中,用的了一些非常数学的手段去提高矩阵运算的速度,其实就是几个公式,然后合并一下,这里不做赘述
在芯片制造上的应用
在芯片制造上的应用是主方法反推的体现。对于完全二叉树的芯片结构就不画图了,但是他的面积为
n
l
g
n
nlgn
nlgn我们是否有办法将这个结构降低到线性的
n
n
n呢?这需要怎样的一种结构呢?
首先n可以被分开为
n
∗
n
\sqrt{n}*\sqrt{n}
n∗n,我们知道什么样的递归式是
Θ
(
n
)
\Theta(\sqrt{n})
Θ(n)呢?由公式可以得到为
T
(
n
)
=
2
T
(
n
/
4
)
+
Θ
(
1
)
T(n) = 2T(n/4)+\Theta(1)
T(n)=2T(n/4)+Θ(1) 那么这是一个怎样的结构呢?