zoukankan      html  css  js  c++  java
  • 常用小算法

    1.快速幂取模

    要求 a^b % c的时候,当然可以直接循环然后每一步都mod c,这样的复杂度就是O(b)了,但是快速模取幂算法可以降低复杂度。

    描述如下:

      可以把b按二进制展开为:b = p(n)*2^n  +  p(n-1)*2^(n-1)  +…+   p(1)*2  +  p(0)

      其中p(i) (0<=i<=n)为 0 或 1

      样 a^b =  a^ (p(n)*2^n  +  p(n-1)*2^(n-1)  +...+  p(1)*2  +  p(0))
                   =  a^(p(n)*2^n)  *  a^(p(n-1)*2^(n-1))  *...*  a^(p(1)*2)  *  a^p(0)
      对于p(i)=0的情况, a^(p(i) * 2^(i-1) ) =  a^0  =  1,不用处理
      我们要考虑的仅仅是p(i)=1的情况
      化简:a^(p(i)*2^i)  = a^(p(i)*2^(i-1)  * 2) = (a^(  p(i)  *  2^(i-1) ) )^2    可由(   (a^b)^c = a^(b*c)   )推理 
      p(i) = 1
        所以a^(2^i) = (a^(2^(i - 1)))^2
      (这里很重要!!具体请参阅秦九韶算法:http://baike.baidu.com/view/1431260.htm
      利用这一点,我们可以递推地算出所有的a^(2^i)
      当然由算法1的结论,我们加上取模运算:
      a^(2^i)%c = ( (a^(2^(i-1)) % c ) * ( a^(2^(i-1)) % c ) 
    下面是求 x^n % mod

     

        //快速模取幂算法
        private static long mod_pow(long x, long n, long mod) {
            long res = 1;
            while(n > 0) {
                if((n & 1) != 0) res = res * x % mod;
                x = x * x % mod;
                n >>= 1;
            }
            return res;
        }

    2.判断素数

        public boolean isPrime(int n) {
            if (n < 2)
                return false;
            int k = (int)Math.sqrt(n);
            for (int i = 2; i <= k; i++) {
                if (n % i == 0)
                    return false;
            }
            return true;
        }

     3.java中在涉及到字符串的增删改查操作时,尽量用StringBuffer。

    4.kmp算法

        public boolean kmp(String par, String ori) {
            int next[] = new int[par.length()+1];
            //求next数组每个元素值
                        
            next[0] = -1;
            int k = -1, j = 0;
            while ( j < par.length()) {
                //k == -1就表示比较到了第一位还不相等,所以next[j] = 0
                //k其实就是next[j-1](k == -1时其实也是),par.charAt(j) == par.charAt(k)满足的话,也就是说next[j] = next[j-1]+1
                //如果不满足那就要从前k个字符的前缀不相等的那一位开始
                if (k == -1 || par.charAt(j) == par.charAt(k)) {
                    next[++j] = ++k;//也就是说next[j] = next[j-1]+1
                } else {
                    k = next[k];//从前k个字符的前缀不相等的那一位开始从新比较
                }
            }
            //            nextArray(par,next);
            int p = 0, q = 0;
            while (p < ori.length()) {
                if (par.charAt(q) == ori.charAt(p)) {
                    if (q == par.length()-1) {
                        q = next[q];
                        return true;
                    } else { //相等则继续往后比较
                        p++;
                        q++;
                    }
                } else { //不相等则移动
                    q = next[q];
                }
                if (q == -1) { //比较了模式串的第一个字符且不相等
                    p++;
                    q++;
                }
            }
            return false;
        }
    View Code

     5.求二叉树高度

        public int getDepth(TreeNode node) {
            if (node == null)
                return 0;
            else 
                return Math.max(getDepth(node.left),getDepth(node.right)) + 1; 
        }
    View Code
  • 相关阅读:
    Goroutine被动调度之一(18)
    实战分析一个运行起来会卡死的Go程序
    Go语言调度器之盗取goroutine(17)
    第三章 Goroutine调度策略(16)
    非main goroutine的退出及调度循环(15)
    Go语言调度器之调度main goroutine(14)
    PHP经典面试题之 Redis 内存满了怎么办?
    【PHP】让新人快速理解ThinkPHP6中的事务操作
    面试官:说说swoole+PHP实现自动取消订单,还原库存等操作
    最新整理的PHP高级面试题来啦!【附答案】
  • 原文地址:https://www.cnblogs.com/fisherinbox/p/5497491.html
Copyright © 2011-2022 走看看