Algorithm Course Review(5.2)

  归纳法这一章里提到的其他算法有整数幂,多项式求值,生成排列和寻找多数元素的算法。
  整数幂算法中,x^n,当指数n为偶数时,可以先求解y=x^(n/2),然后y=y^2即得到结果,当n是基数时,y=x^((n-1)/2),y=y^2,y=xy,只需要补充一步。当然,求解x^(n/2)是直接递归调用整数幂的过程。

  多项式求值,将多项式改写为嵌套乘法的形式,以减少乘法操作的次数,使得算法加速。在http://www.cnblogs.com/skyivben/archive/2012/05/13/2497900.html#2376283 测试了这种优化方法,得出了一些很有意思的结果。

  生成排列,给出了两种过程,可以概括一下,一种方法是,将1固定在第一个位置,后面的2,3..n生成排列,然后2固定在第一个位置,剩下的1,3..n生成排列。在用2,3..n生成排列的时候,2固定在第一个位置,3..n生成排列,递归下去。另一个方法是,生成1,..(n-1)的一个排列,然后把n插入这个排列之中。由于总排列数是n!,两种过程的时间复杂度都是nn!。

  寻找多数元素
  如果元素在序列A[1..n]中出现的次数多于n/2,称之为多数元素。n为偶数的时候占一半的元素并不称为多数元素。所以一个序列,要么有多数元素,要么没有,而不会出现有两个多数元素。
  考虑到一个其他元素出现一次,多数元素就应该出现一次。所以对一个元素a计数,如果又出现这个元素,那么a出现次数加1,如果出现其它元素,那么a的次数减1.如果计数为0了,那么可以从后面从新开始找多数元素。如果a是多数元素,a一定会坚持到最后。但是如果这个序列本身没有多数元素,那么最后也会有一个元素到最后。所以找到一个多数元素之后需要检查它是否确实为多数元素。
  代码如下,

int candicate(vector<int>& A,int m)
{
    int j = m;
    int c = A[m];
    int cnt = 1;
    int n = A.size();
    while(j<n && cnt>0)
    {
        j++;
        if(A[j]==c)
            cnt++;
        else
            cnt--;
    }
    if(j==n)
        return c;
    else
        return candicate(A,j+1);
}

bool majority(vector<int>& A,int& m)
{
    int c = candicate(A,1);
    int cnt = 0;
    int n = A.size();
    for(int j=0;j<n;j++)
        if(A[j]==c)
            cnt++;
    if(cnt>n/2)
    {
        m = c;
        return true;
    }
    else
        return false;
}    

  归纳法最主要的问题就是找出递推关系,算法可以用递归实现,有时也可以用迭代实现。

posted @ 2012-05-15 20:42  Frandy.CH  阅读(204)  评论(0编辑  收藏  举报