时间复杂度O(log n)分析

让我详细解释如何分析这段代码的时间复杂度:

🔍 代码逐行分析

@Test
public void test2(int n) {
    int sum = 1;          // 1. 初始化操作,时间复杂度: O(1)
    while (sum < n) {     // 2. 循环条件判断
        sum *= 2;         // 3. 循环体内的操作,时间复杂度: O(1)
    }
    System.out.println(sum); // 4. 输出操作,时间复杂度: O(1)
}

📊 时间复杂度计算过程

循环执行次数分析

让我们追踪循环的执行过程:

循环次数sum的值数学表达式
012⁰ = 1
122¹ = 2
242² = 4
382³ = 8
4162⁴ = 16
.........
k2ᵏ2ᵏ

数学推导

循环会在满足以下条件时停止:

text

2ᵏ ≥ n

对两边取对数:

text

k ≥ log₂n

因此,循环次数为:⌈log₂n⌉(向上取整)

🎯 时间复杂度结论

总时间复杂度:O(log n)

  • 最好情况:O(1) - 当 n ≤ 1 时,循环不执行

  • 最坏情况:O(log n) - 当 n 很大时

  • 平均情况:O(log n)

📈 可视化理解

text

n值       循环次数   时间复杂度
n=1       0         O(1)
n=2       1         O(1)
n=4       2         O(2)
n=8       3         O(3)
n=16      4         O(4)
n=32      5         O(5)
n=1024    10        O(10)
n=1048576 20        O(20)

可以看到,当n增长100万倍时,循环次数只从10增加到20!

🔢 与其他复杂度的对比

// O(1) - 常数时间
int sum = n * (n + 1) / 2;

// O(log n) - 对数时间(你的代码)
while (sum < n) {
    sum *= 2;
}

// O(n) - 线性时间
for (int i = 0; i < n; i++) {
    // 操作
}

// O(n²) - 平方时间
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        // 操作
    }
}

🧠 判断时间复杂度的技巧

  1. 识别循环结构

  2. 分析循环变量的变化方式

    • 每次加固定值:O(n)

    • 每次乘固定值:O(log n)

    • 每次指数增长:O(log log n)

  3. 计算循环次数

  4. 忽略常数项和低阶项

📝 练习:判断其他类似代码

// 例1:时间复杂度是多少?
int i = 1;
while (i < n) {
    i *= 3;  // O(log₃n) = O(log n)
}

// 例2:时间复杂度是多少?
int j = n;
while (j > 1) {
    j /= 2;  // O(log n)
}

// 例3:时间复杂度是多少?
int k = 1;
while (k < n) {
    k += 5;  // O(n) - 线性时间
}

✅ 总结

你的代码 test2(int n) 的:

  • 时间复杂度:O(log n)

  • 空间复杂度:O(1) - 只使用了固定数量的变量

  • 效率等级:高效算法(对数时间复杂度很好)

这是因为循环变量 sum 以指数速度增长(每次乘以2),所以只需要很少的循环次数就能达到目标值n。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值