剑指Offer-专题-代码完整性

代码的完整性


数值的整数次方

分析

GET到新技能,二分法和位运算法

二分法

设 2 n , ( n > 0 ) ; 设2^n,(n>0); 2n,(n>0);
当n为偶数:

2 n = 2 n 2 × 2 n 2 2^n = 2^{\frac{n}{2}} \times 2^{\frac{n}{2}} 2n=22n×22n
2 n 2 = 2 n 4 × 2 n 4 2^{\frac{n}{2}} = 2^{\frac{n}{4}} \times 2^{\frac{n}{4}} 22n=24n×24n
2 n 4 = 2 n 8 × 2 n 8 2^{\frac{n}{4}} = 2^{\frac{n}{8}} \times 2^{\frac{n}{8}} 24n=28n×28n


当n为奇数:
2 n = 2 n 2 × 2 n 2 × 2 2^n = 2^{\frac{n}{2}} \times 2^{\frac{n}{2}} \times 2 2n=22n×22n×2
分解如上

可以推出:

exponent为偶数:
b a s e e x p o n e n t = b a s e e x p o n e n t 2 × b a s e e x p o n e n t 2 base^{exponent} = base^{\frac{exponent}{2}} \times base^{\frac{exponent}{2}} baseexponent=base2exponent×base2exponent


exponent为奇数:
b a s e e x p o n e n t = b a s e e x p o n e n t − 1 2 × b a s e e x p o n e n t − 1 2 base^{exponent} = base^{\frac{exponent-1}{2}} \times base^{\frac{exponent-1}{2}} baseexponent=base2exponent1×base2exponent1

这样不断分解到最后,时间复杂度可以将为 O ( l o g n ) O(logn) O(logn)

位运算

思路来自二进制转十进制的运算,注意当幂数为奇数的时候

( 1 ) 2 = 2 0 = 1 ({1})_2 = 2^0 = 1 (1)2=20=1
( 10 ) 2 = 2 1 = 2 ({10})_2 = 2^1 = 2 (10)2=21=2
( 11 ) 2 = 2 1 + 2 0 = 2 + 1 = 3 ({11})_2 = 2^1 + 2^0 = 2 + 1 = 3 (11)2=21+20=2+1=3
( 100 ) 2 = 2 2 = 4 ({100})_2 = 2^2 = 4 (100)2=22=4
( 101 ) 2 = 2 2 + 2 0 = 4 + 1 = 5 ({101})_2 = 2^2 + 2^0 = 4 + 1 = 5 (101)2=22+20=4+1=5
↓ \downarrow
3 5 = 3 ( 101 ) 2 = 3 2 2 + 2 0 = 3 2 2 × 3 2 0 = 3 4 × 3 1 3^5 = 3^{({101})_2} = 3^{2^2+2^0} = 3^{2^2} \times 3^{2^0} = 3^4 \times 3^1 35=3(101)2=322+20=322×320=34×31

代码

// 简单方法
public class Solution {
    public double Power(double base, int exponent) {
        // 因为考察代码完整性,这三个特殊样例直接返回
        if ( base == 0 )     return 0;
        if ( exponent == 0 ) return 1;
        if ( exponent == 1 ) return base;
        
        double target = 1;

        int exp = exponent > 0 ? exponent : -exponent;

        for (int i = 1; i <= exp; i++ ){
            target *= base;
        }

        return exponent > 0 ? target : 1 / target;
      }
}



// 传说中的快速幂算法(二分)

public static double getPower( double base, int exponent ){
        int n = exponent > 0 ? exponent : -exponent;
        double target = binaryPower(base, n);
        return exponent > 0 ? target : 1/target;
    }
    public static double binaryPower(double base, int exponent){
        if ( exponent == 0 ) return 1;
        if ( exponent == 1 ) return base;
        if ( base == 0 )     return 0;

        double subTarget = binaryPower(base, exponent>>1);
        return exponent % 2 == 1 ? subTarget * subTarget * base : subTarget * subTarget;
    }



// 位运算
public class Solution {
    public double Power(double base, int exponent) {
        if ( exponent == 0 ) return 1;
        if ( exponent == 1 ) return base;
        if ( base == 0 )     return 0;

        int n = exponent > 0 ? exponent : -exponent;

        double target = 1;

        while (n != 0 ){
            if ( (n & 1) == 1 ){
                target *= base;
            }
            
            // n^2,n^4,n^8……
            base = base * base;

            n = n>>1;
        }
        
        /*
        for(;n != 0; n = n>>1){
            if ( (n & 1) == 1 ){
                target *= base;
            }
            base = base * base;
        }
        */
        return exponent > 0 ? target : 1 / target;
      }
}

调整数组顺序使奇数位于偶数前面

分析

插入排序法,加个哨兵k,负责看管奇数(奇数二进制最右位为1,做与运算可以判断)

代码

public class Solution {
    public void reOrderArray(int [] array) {
        if( array == null || array.length == 0 ){
            return ;
        }
        int k = 0;

        for( int i = 0; i < array.length; i++ ) {
            if( (array[i] & 1) != 0 ){
                int tmp = array[i];
                int j = i;
                while( j > k ){
                    array[j] = array[j-1];
                    j--;
                }
                k = j + 1;
                array[j] = tmp;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值