509 斐波那契数
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。
class Solution {
public int fib(int n) {
if (n < 2) {
return n;
}
int p = 0, q = 0, r = 1;
for (int i = 2; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
}
迭代更新:
使用一个for循环从2到n,逐步计算斐波那契数列的值。
在每次循环中,p被更新为前一个数列的第二项(即q),q更新为前一个数列的第三项(即r),r更新为p和q的和,即当前的斐波那契数值。
爬楼梯
思路和算法
我们用 f(x) 表示爬到第 x 级台阶的方案数,考虑最后一步可能跨了一级台阶,也可能跨了两级台阶,所以我们可以列出如下式子:
f(x)=f(x−1)+f(x−2)
它意味着爬到第 x 级台阶的方案数是爬到第 x−1 级台阶的方案数和爬到第 x−2 级台阶的方案数的和。很好理解,因为每次只能爬 1 级或 2 级,所以 f(x) 只能从 f(x−1) 和 f(x−2) 转移过来,而这里要统计方案总数,我们就需要对这两项的贡献求和。
以上是动态规划的转移方程,下面我们来讨论边界条件。我们是从第 0 级开始爬的,所以从第 0 级爬到第 0 级我们可以看作只有一种方案,即 f(0)=1;从第 0 级到第 1 级也只有一种方案,即爬一级,f(1)=1。这两个作为边界条件就可以继续向后推导出第 n 级的正确结果。我们不妨写几项来验证一下,根据转移方程得到 f(2)=2,f(3)=3,f(4)=5,……,我们把这些情况都枚举出来,发现计算的结果是正确的。
我们不难通过转移方程和边界条件给出一个时间复杂度和空间复杂度都是 O(n) 的实现,但是由于这里的 f(x) 只和 f(x−1) 与 f(x−2) 有关,所以我们可以用「滚动数组思想」把空间复杂度优化成 O(1)。
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;
}
}
231 2的幂
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
示例 1:
输入:n = 1
输出:true
解释:20 = 1
官方解:
class Solution {
public boolean isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
}
大佬解:求log2(n),结果是整数
class Solution {
public boolean isPowerOfTwo(int n) {
if (n <= 0) {
return false;
}
// 计算以2为底的对数
double log2n = Math.log(n) / Math.log(2);
// 使用 Math.floor 来避免精度问题,比较是否为整数
return log2n == Math.floor(log2n);
}
}
342. 4的幂
和2的幂一样的做法,但不能完全依靠Math.Floor(只能减少精度的丢失),我用它做3的幂就有数不能过
326 3的幂
class Solution {
public boolean isPowerOfThree(int n) {
if (n <= 0) {
return false;
}
// 反复除以3直到得到1
while (n % 3 == 0) {
n /= 3;
}
// 如果最后n是1,说明它是3的幂
return n == 1;
}
}
504. 七进制数
class Solution {
public String convertToBase7(int num) {
if (num == 0) return "0";
StringBuilder sb = new StringBuilder();
int n = Math.abs(num);//对num取绝对值
while (n > 0) {
sb.append(n % 7);
n /= 7;
}
if (num < 0) sb.append("-");
sb.reverse();//StringBuilder的反转方法
return sb.toString();
}
}
10转R进制模板
class Solution {
public:
string convertToBase7(int num) {
return tenToR(num, 7);
}
private:
const string words = "0123456789abcdef";
string tenToR(int num, const int R) {
// 特判0
if (num == 0) {
return "0";
}
// 处理负数
long long n = num;
string flag;
if (n < 0) {
flag = "-";
n = -n;
}
string s;
while(n) {
int idx = n%R;
n /= R;
s += words[idx];
}
reverse(s.begin(), s.end());
return flag + s;
}
};
263.丑数
除了235能除其他不行
解释:for (int factor : factors) 这种语法结构被称为“增强型 for 循环”(Enhanced For Loop)或“for-each 循环”。它提供了一种简洁的方式来遍历数组或实现了 Iterable 接口的集合(如 List, Set 等)。
示例
如果你有一个整数数组 factors,你可以这样遍历它:
int[] factors = {2, 3, 5, 7};
for (int factor : factors) {
System.out.println(factor);
}
输出将会是:
2
3
5
7
对于集合,比如 List,使用方式类似:
List<Integer> factorsList = Arrays.asList(2, 3, 5, 7);
for (int factor : factorsList) {
System.out.println(factor);
}
class Solution {
public boolean isUgly(int n) {
if (n <= 0) {
return false;
}
int[] factors = {2, 3, 5};
for (int factor : factors) {
while (n % factor == 0) {
n /= factor;
}
}
return n == 1;
}
}
190 颠倒二进制位
把二进制倒过来
官解:
public class Solution {
public int reverseBits(int n) {
int rev = 0;
for (int i = 0; i < 32 && n != 0; ++i) {
rev |= (n & 1) << (31 - i);
n >>>= 1;
}
return rev;
}
}
大佬:调用jdk方法
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
return Integer.reverse(n);
}
}
191 位1的个数
二进制位1的个数
官解:
public class Solution {
public int hammingWeight(int n) {
int ret = 0;
for (int i = 0; i < 32; i++) {
if ((n & (1 << i)) != 0) {
ret++;
}
}
return ret;
}
}
我的:
class Solution {
public int hammingWeight(int n) {
int count=0;
while(n!=0){
if(n%2==1){
count++;
n/=2;
}else{
n/=2;
}
}
return count;
}
}
461. 汉明距离
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
给你两个整数 x 和 y,计算并返回它们之间的汉明距离。
示例 1:
输入:x = 1, y = 4
输出:2
解释:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
上面的箭头指出了对应二进制位不同的位置。
我的:
class Solution {
public int hammingDistance(int x, int y) {
// 计算 x 和 y 的异或结果
int xor = x ^ y;
int count = 0;
// 统计异或结果中1的个数,即汉明距离
while (xor != 0) {
// 如果最低位是1,增加计数器
count += (xor & 1);
// 右移一位处理下一个二进制位
xor >>= 1;
}
return count;
}
}
官解:
class Solution {
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
}