本章由兩個問題引開,並證明了一些算法基礎的數學公式。
1. 兩個問題
a. 求N個數中的前K個最大值問題。從全部排序法,到維持一個K個元素的數組方法,再到2叉堆法,一步一步說明算法重要性。
b. 字謎問題。
2. 數學公式
指數問題,對數問題,級數和問題。
3. 一些數學證明方法
a.數學歸納法。 兩要素:基準情形成立,當n=N成立時,n=N+1也成立,得證。
b.遞歸方法。兩要素:停止條件,不斷推進
4. 大O表示法
單循環爲O(N),嵌套兩層爲O(N2),分治2分爲logN. 斐波拉契爲(5/3)N次方
例子:最大子序列最大和問題的求解。
窮舉法,窮舉所有數列,2分法還有一個用技巧的O(N)算法。代碼如下:
#include <stdio.h>
int maxSubSeqence(const int A[],unsigned int n)
{
int i,j,k=0;
int sum,maxsum=0;
for(i=0;i<n;i++)
for(j=i;j<n;j++)
{
sum =0;
for(k=i;k<=j;k++)
sum = sum + A[k];
if (sum>maxsum)
maxsum = sum ;
}
return maxsum;
}
int maxSubSeqence2(const int A[],unsigned int n)
{
int i,j,k=0;
int sum,maxsum=0;
for(i=0;i<n;i++)
{
sum =0;
for(j=i;j<n;j++)
{
sum = sum + A[j];
if (sum>maxsum)
maxsum = sum ;
}
}
return maxsum;
}
int maxSubSeqence3(const int A[],int begin, int end)
{
if (begin==end)
{
if (A[begin]>0)
return A[begin];
else
return 0;
}
int middle =(begin+end)/2;
int leftsum,rightsum;
leftsum = maxSubSeqence3(A,begin,middle);
rightsum = maxSubSeqence3(A,middle+1,end);
int maxleftbordersum=0,maxrightbordersum=0, bordersum=0;
int i;
for(i = middle+1;i<=end; i++)
{
bordersum = bordersum+ A[i];
if (bordersum>maxrightbordersum)
maxrightbordersum = bordersum;
}
bordersum =0;
for(i = middle;i>=begin; i--)
{
bordersum = bordersum+ A[i];
if (bordersum>maxleftbordersum)
maxleftbordersum = bordersum;
}
int max = leftsum;
if (max<rightsum)
max =rightsum;
if (max<maxleftbordersum+maxrightbordersum)
max =maxleftbordersum+maxrightbordersum;
return max;
}
int maxSubSeqence4(const int A[],int n)
{
int i=0,max =0;
int sum=0;
for (i=0;i<n;i++)
{
sum=sum+A[i]; if(sum>max)
max= sum;
if(sum<0)
sum =0;
}
return max;
}
int main()
{
int A[] = {1,-3, 9,2,1, -10,6,-7,8} ;
int maxsum = maxSubSeqence(A,sizeof(A)/sizeof(int));
printf("maxsum=%d\n",maxsum);
int maxsum2 = maxSubSeqence2(A,sizeof(A)/sizeof(int));
printf("maxsum2=%d\n",maxsum2);
int maxsum3 = maxSubSeqence3(A,0,sizeof(A)/sizeof(int)-1);
printf("maxsum3=%d\n",maxsum3);
int maxsum4 = maxSubSeqence4(A,sizeof(A)/sizeof(int));
printf("maxsum4=%d\n",maxsum4);
return 0;
}
logN的算法歐幾里得求解最大公約數:
#include <stdio.h>
int gcd(int m, int n)
{
while(n>0)
{
int rem = m%n;
m = n;
n = rem;
}
return m;
}
int main()
{
int m = 1345, n = 9745;
printf("gcd = %d\n", gcd(m,n));
}
~
求x的N次方運算:
#include <stdio.h>
int power(int x,int n)
{
if (n==0)
return 1;
if (n==1)
return x;
if (n%2==0)
return power(x*x,n/2);
else
return power(x*x,(n-1)/2)* x;
}
int main()
{
int m = power(2,10);
printf("power 2,10=%d\n", m);
}