• 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;
    }    

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

  • 相关阅读:
    【URAL1039】Anniversary Party
    【POJ2480】Longge's problem
    【POJ2478】Farey Sequence
    【HDU2157】How many ways??
    【NOI2012】随机数生成器
    【HDU3306】Another kind of Fibonacci
    【HDU2604】Queuing
    【HDU1757】A Simple Math Problem
    【HDU1575】Tr A
    【HDU1521】排列组合
  • 原文地址:https://www.cnblogs.com/Frandy/p/algorithm_course_5_2.html
Copyright © 2020-2023  润新知