代码的完整性
数值的整数次方
分析
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=base2exponent−1×base2exponent−1
这样不断分解到最后,时间复杂度可以将为 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;
}
}
}
}