|
| 1 | +### 一 数值的整数次方 |
| 2 | +#### **题目描述:** |
| 3 | +给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 |
| 4 | +#### **问题解析:** |
| 5 | +这道题算是比较麻烦和难一点的一个了。我这里采用的是**二分幂**思想,当然也可以采用**快速幂**。 |
| 6 | +更具剑指offer书中细节,该题的解题思路如下: |
| 7 | +1.当底数为0且指数<0时,会出现对0求倒数的情况,需进行错误处理,设置一个全局变量; |
| 8 | +2.判断底数是否等于0,由于base为double型,所以不能直接用==判断 |
| 9 | +3.优化求幂函数(二分幂)。 |
| 10 | +当n为偶数,a^n =(a^n/2)*(a^n/2); |
| 11 | +当n为奇数,a^n = a^[(n-1)/2] * a^[(n-1)/2] * a。时间复杂度O(logn) |
| 12 | + |
| 13 | +**时间复杂度**:O(logn) |
| 14 | +#### **示例代码:** |
| 15 | +```java |
| 16 | +public class Solution { |
| 17 | + boolean invalidInput=false; |
| 18 | + public double Power(double base, int exponent) { |
| 19 | + //如果底数等于0并且指数小于0 |
| 20 | + //由于base为double型,不能直接用==判断 |
| 21 | + if(equal(base,0.0)&&exponent<0){ |
| 22 | + invalidInput=true; |
| 23 | + return 0.0; |
| 24 | + } |
| 25 | + int absexponent=exponent; |
| 26 | + //如果指数小于0,将指数转正 |
| 27 | + if(exponent<0) |
| 28 | + absexponent=-exponent; |
| 29 | + //getPower方法求出base的exponent次方。 |
| 30 | + double res=getPower(base,absexponent); |
| 31 | + //如果指数小于0,所得结果为上面求的结果的倒数 |
| 32 | + if(exponent<0) |
| 33 | + res=1.0/res; |
| 34 | + return res; |
| 35 | + } |
| 36 | + //比较两个double型变量是否相等的方法 |
| 37 | + boolean equal(double num1,double num2){ |
| 38 | + if(num1-num2>-0.000001&&num1-num2<0.000001) |
| 39 | + return true; |
| 40 | + else |
| 41 | + return false; |
| 42 | + } |
| 43 | + //求出b的e次方的方法 |
| 44 | + double getPower(double b,int e){ |
| 45 | + //如果指数为0,返回1 |
| 46 | + if(e==0) |
| 47 | + return 1.0; |
| 48 | + //如果指数为1,返回b |
| 49 | + if(e==1) |
| 50 | + return b; |
| 51 | + //e>>1相等于e/2,这里就是求a^n =(a^n/2)*(a^n/2) |
| 52 | + double result=getPower(b,e>>1); |
| 53 | + result*=result; |
| 54 | + //如果指数n为奇数,则要再乘一次底数base |
| 55 | + if((e&1)==1) |
| 56 | + result*=b; |
| 57 | + return result; |
| 58 | + } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +当然这一题也可以采用笨方法:累乘。不过这种方法的时间复杂度为O(n),这样没有前一种方法效率高。 |
| 63 | +```java |
| 64 | + // 使用累乘 |
| 65 | + public double powerAnother(double base, int exponent) { |
| 66 | + double result = 1.0; |
| 67 | + for (int i = 0; i < Math.abs(exponent); i++) { |
| 68 | + result *= base; |
| 69 | + } |
| 70 | + if (exponent >= 0) |
| 71 | + return result; |
| 72 | + else |
| 73 | + return 1 / result; |
| 74 | + } |
| 75 | +``` |
| 76 | +### 二 调整数组顺序使奇数位于偶数前面 |
| 77 | +#### **题目描述:** |
| 78 | +输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 |
| 79 | + |
| 80 | +#### **问题解析:** |
| 81 | +这道题有挺多种解法的,给大家介绍一种我觉得挺好理解的方法: |
| 82 | +我们首先统计奇数的个数假设为n,然后新建一个等长数组,然后通过循环判断原数组中的元素为偶数还是奇数。如果是则从数组下标0的元素开始,把该奇数添加到新数组;如果是偶数则从数组下标为n的元素开始把该偶数添加到新数组中。 |
| 83 | + |
| 84 | +#### **示例代码:** |
| 85 | +时间复杂度为O(n),空间复杂度为O(n)的算法 |
| 86 | +```java |
| 87 | +public class Solution { |
| 88 | + public void reOrderArray(int [] array) { |
| 89 | + //如果数组长度等于0或者等于1,什么都不做直接返回 |
| 90 | + if(array.length==0||array.length==1) |
| 91 | + return; |
| 92 | + //oddCount:保存奇数个数 |
| 93 | + //oddBegin:奇数从数组头部开始添加 |
| 94 | + int oddCount=0,oddBegin=0; |
| 95 | + //新建一个数组 |
| 96 | + int[] newArray=new int[array.length]; |
| 97 | + //计算出(数组中的奇数个数)开始添加元素 |
| 98 | + for(int i=0;i<array.length;i++){ |
| 99 | + if((array[i]&1)==1) oddCount++; |
| 100 | + } |
| 101 | + for(int i=0;i<array.length;i++){ |
| 102 | + //如果数为基数新数组从头开始添加元素 |
| 103 | + //如果为偶数就从oddCount(数组中的奇数个数)开始添加元素 |
| 104 | + if((array[i]&1)==1) |
| 105 | + newArray[oddBegin++]=array[i]; |
| 106 | + else newArray[oddCount++]=array[i]; |
| 107 | + } |
| 108 | + for(int i=0;i<array.length;i++){ |
| 109 | + array[i]=newArray[i]; |
| 110 | + } |
| 111 | + } |
| 112 | +} |
| 113 | +``` |
0 commit comments