50. Pow(x, n)
实现 pow(x, n) ,即计算 x
的整数 n
次幂函数(即,xn
)。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
提示:
-100.0 < x < 100.0
-231 <= n <= 231-1
n
是一个整数- 要么
x
不为零,要么n > 0
。 -104 <= xn <= 104
class Solution {
public double myPow(double x, int n) {
double res = 1.0;
for(int i = n; i != 0; i /= 2){
if(i % 2 != 0){
res *= x;
}
x *= x;
}
return n < 0 ? 1 / res : res;
}
}
- 初始化结果:首先,方法初始化一个名为
res
的变量为1.0,用于存储最终的结果。 - 循环计算:通过一个
for
循环,从n
开始,每次迭代都将i
除以2(即i /= 2
),直到i
变为0。循环的目的是利用幂的性质减少乘法操作的次数。
- 奇数幂次:如果当前的
i
是奇数(i % 2 != 0
),则将当前的x
值乘到res
上。这是因为x^n
可以分解为x^(2k+1) = x^(2k) * x
,其中2k+1
是奇数,2k
是偶数。 - 平方基数:每次迭代,无论
i
是否为奇数,都将x
自身乘以x
(即x *= x
),这是为了准备计算下一个偶数幂次。这利用了幂的性质x^(2k) = (x^2)^k
。
- 处理负指数:如果
n
是负数,表示需要计算x
的负n
次幂,即1 / (x^n)
。因此,在返回结果前,检查n
是否小于0,如果是,则返回1 / res
,否则返回res
。
70. 爬楼梯
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示:
1 <= n <= 45
class Solution {
public int climbStairs(int n) {
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
}
- 初始化变量:
p
,q
,r
初始值都设为 0,但在循环开始前,r
被赋值为 1。这里,p
,q
,r
分别用于存储到达当前阶梯之前两个阶梯、前一个阶梯和当前阶梯的不同方法数。 - 循环计算:通过一个从 1 到 n 的循环,逐步计算出到达每一阶楼梯的不同方法数。
p = q;
:首先,将q
(到达前一阶楼梯的方法数)赋值给p
,因为p
代表到达当前阶梯前两个阶梯的方法数,在更新q
和r
之前需要先保存q
的值。q = r;
:然后,将r
(到达当前阶梯前一阶的方法数)赋值给q
,为下一轮迭代准备。r = p + q;
:最后,更新r
的值,它现在代表到达当前阶梯的不同方法总数,即到达前两个阶梯的方法数 (p
) 加上到达前一个阶梯的方法数 (q
)。
- 返回结果:循环结束后,
r
中存储的就是到达楼顶(第 n 阶楼梯)的不同方法总数。
198. 打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 400
class Solution {
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int n = nums.length;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = nums[0];
for (int i = 2; i <= n; i++) {
dp[i] = Math.max(dp[i-1], nums[i-1] + dp[i-2]);
}
return dp[n];
}
}
- 函数定义:
public int rob(int[] nums)
定义了一个公开的方法rob
,它接受一个整数数组nums
作为参数,并返回一个整数,表示在不连续偷盗房屋的情况下能够偷到的最高金额。 - 边界条件:首先检查数组
nums
是否为空(nums.length == 0
)。如果是,直接返回 0,因为没有房屋可以偷盗。 - 变量初始化:
int n = nums.length;
获取数组nums
的长度。int[] dp = new int[n+1];
创建一个长度为n+1
的动态规划数组dp
。这里使用n+1
是为了方便处理边界情况,dp[i]
将表示偷盗前i
个房屋(即考虑到第i-1
个房屋)能得到的最大金额。dp[0] = 0;
初始化,表示偷盗前 0 个房屋(即没有任何房屋)能得到的最大金额为 0。dp[1] = nums[0];
初始化,表示偷盗第 1 个房屋(即数组中的第一个房屋)能得到的最大金额为该房屋中的金额。
- 动态规划逻辑:
- 使用一个循环从
2
遍历到n
(包括n
),计算dp[i]
的值。 - 对于每个
i
,dp[i]
的值取决于两个因素:
- 如果不偷盗第
i-1
个房屋(即考虑前i-1
个房屋的最大金额),则dp[i] = dp[i-1]
。 - 如果偷盗第
i-1
个房屋(这意味着不能偷盗第i-2
个房屋),则dp[i] = nums[i-1] + dp[i-2]
。
dp[i]
的最终值为上述两种情况中的最大值,即dp[i] = Math.max(dp[i-1], nums[i-1] + dp[i-2])
。
- 返回结果:循环结束后,
dp[n]
中存储的就是偷盗前n
个房屋(即考虑数组中所有房屋)能得到的最大金额。因此,方法返回dp[n]
。