Skip to content

Commit 5f7bafc

Browse files
update
1 parent 0b174aa commit 5f7bafc

1 file changed

Lines changed: 86 additions & 83 deletions

File tree

算法/剑指 offer.md

Lines changed: 86 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -468,89 +468,6 @@ class Solution {
468468

469469

470470

471-
# [16、数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/)
472-
473-
2020/09/13
474-
475-
这道题看似简单其实暗藏了各种边界条件的判断::x = 0、n = 0、n = 1、n < 0 等等。
476-
477-
此题的主要运用了二分查找和位运算的方式解决
478-
479-
1. Java 代码中 int32 变量 $n \in [-2147483648, 2147483647] $,因此当 $n = -2147483648$ 时执行 $n = -n$ 会因越界而赋值出错。解决方法是先将 n 存入 ==long== 变量 exponent ,后面用 exponent 操作即可。
480-
2. 要注意 result 类型必须是 double 否则会出现精度丢失
481-
3. $$a^n = \begin{cases} a^{n/2} * a^{n/2} & \text{$n 为偶数$} \\a^{(n - 1)/2} * a^{(n - 1)/2} & \text {$n 为奇数$}\end{cases} $$
482-
483-
484-
485-
## 解法1:递推,时间复杂度 O(logn)、空间复杂度O(1)
486-
487-
```java
488-
class Solution {
489-
public double myPow(double x, int n) {
490-
// 0 的任何次方都无意义。
491-
if (x == 0) {
492-
return 0;
493-
}
494-
// 任何数的 0 次方都等于 1
495-
if (n == 0) {
496-
return 1;
497-
}
498-
// 任何数的 1 次方都等于原数字
499-
if (n == 1) {
500-
return x;
501-
}
502-
// 见上文解释
503-
long exponent = n;
504-
// 如果 n < 0 着进行转化
505-
if (exponent < 0) {
506-
x = 1 / x;
507-
exponent = -exponent;
508-
}
509-
double result = 1;
510-
// 快速幂等算法
511-
while (exponent > 0) {
512-
// 判断二进制最右一位是否为 1,为 1 即为奇数
513-
if ((exponent & 1) == 1) {
514-
result *= x;
515-
}
516-
// 每次计算都计算 x^2 即可
517-
x *= x;
518-
// 相当于除以 2
519-
exponent >>= 1;
520-
}
521-
return result;
522-
}
523-
}
524-
```
525-
526-
## 解法2: 递归,时间复杂度 O(logn)、空间复杂度O(n)
527-
528-
```java
529-
class Solution {
530-
public double myPow(double x, int n) {
531-
if (x == 0) {
532-
return 0;
533-
}
534-
if (n == 0) {
535-
// 任何数的 0 次方都等于 1
536-
return 1;
537-
}
538-
if (n == 1) {
539-
// 任何数的 1 次方都等于原数字
540-
return x;
541-
}
542-
long exponent = n;
543-
if (exponent < 0) {
544-
x = 1 / x;
545-
exponent = -exponent;
546-
}
547-
// 使用公式完成递推
548-
return ((exponent & 1) == 1) ? x * myPow(x * x, (int)(exponent >> 1))
549-
:myPow(x * x, (int)(exponent >> 1)) ;
550-
}
551-
}
552-
```
553-
554471

555472

556473
## [33、二叉搜索树的后序遍历序列](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/)
@@ -702,6 +619,92 @@ class Solution {
702619

703620

704621

622+
## [16、数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/)
623+
624+
2020/09/13
625+
626+
这道题看似简单其实暗藏了各种边界条件的判断::x = 0、n = 0、n = 1、n < 0 等等。
627+
628+
此题的主要运用了二分查找和位运算的方式解决
629+
630+
1. Java 代码中 int32 变量 $n \in [-2147483648, 2147483647] $,因此当 $n = -2147483648$ 时执行 $n = -n$ 会因越界而赋值出错。解决方法是先将 n 存入 ==long== 变量 exponent ,后面用 exponent 操作即可。
631+
2. 要注意 result 类型必须是 double 否则会出现精度丢失
632+
3. $$a^n = \begin{cases} a^{n/2} * a^{n/2} & \text{$n 为偶数$} \\a^{(n - 1)/2} * a^{(n - 1)/2} & \text {$n 为奇数$}\end{cases} $$
633+
634+
635+
636+
## 解法1:递推,时间复杂度 O(logn)、空间复杂度O(1)
637+
638+
```java
639+
class Solution {
640+
public double myPow(double x, int n) {
641+
// 0 的任何次方都无意义。
642+
if (x == 0) {
643+
return 0;
644+
}
645+
// 任何数的 0 次方都等于 1
646+
if (n == 0) {
647+
return 1;
648+
}
649+
// 任何数的 1 次方都等于原数字
650+
if (n == 1) {
651+
return x;
652+
}
653+
// 见上文解释
654+
long exponent = n;
655+
// 如果 n < 0 着进行转化
656+
if (exponent < 0) {
657+
x = 1 / x;
658+
exponent = -exponent;
659+
}
660+
// !易错点:不是所有的初始值都是 0,写成了 result = 0
661+
double result = 1;
662+
// 快速幂等算法
663+
while (exponent > 0) {
664+
// 判断二进制最右一位是否为 1,为 1 即为奇数
665+
if ((exponent & 1) == 1) {
666+
result *= x;
667+
}
668+
// 每次计算都计算 x^2 即可
669+
x *= x;
670+
// 相当于除以 2
671+
exponent >>= 1;
672+
}
673+
return result;
674+
}
675+
}
676+
```
677+
678+
## 解法2: 递归,时间复杂度 O(logn)、空间复杂度O(n)
679+
680+
```java
681+
class Solution {
682+
public double myPow(double x, int n) {
683+
if (x == 0) {
684+
return 0;
685+
}
686+
if (n == 0) {
687+
// 任何数的 0 次方都等于 1
688+
return 1;
689+
}
690+
if (n == 1) {
691+
// 任何数的 1 次方都等于原数字
692+
return x;
693+
}
694+
long exponent = n;
695+
if (exponent < 0) {
696+
x = 1 / x;
697+
exponent = -exponent;
698+
}
699+
// 使用公式完成递推
700+
return ((exponent & 1) == 1) ? x * myPow(x * x, (int)(exponent >> 1))
701+
:myPow(x * x, (int)(exponent >> 1)) ;
702+
}
703+
}
704+
```
705+
706+
707+
705708
## [51. 数组中的逆序对](https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/o58jfs/)
706709

707710
这道题是典型的归并排序题,是需要写出排序算法,并统计 “逆序对” 的数量即可。

0 commit comments

Comments
 (0)