You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求解给定normalize算法的代价函数(时间复杂度)

算法时间复杂度分析与优化建议

问题背景

我花了数小时思考和谷歌搜索,仍无法确定如何求解该算法的代价函数,也不确定自己的思路是否正确,希望能获得更高效、简便的解题方法建议,感谢帮助!

待分析的算法代码

public float[] normalize (float[] seq) {
  int n = seq.length;
  float sum = 0;
  int cnt = 0;
  int i;
  for (i = 1; i < n; i = i + i ) {
    for ( int j = 0; j < i; j++) {
      sum = sum + seq [j];
    }
    cnt += i;
  }
  float[] res = new float [n];
  while (i >= 0) {
    if (i < n) {
      res [i] = seq[i] / (sum / cnt);
    }
  i--;
  }
  return res;
}

时间复杂度分析

思路纠正

你当前认为算法时间复杂度是O(n log n),这个结论是错误的,正确的时间复杂度应为O(n),详细分析如下:

  • 外层for循环:i从1开始每次翻倍,直到i >= n停止,循环执行次数为log₂n次(比如n=8时,i取1、2、4,共3次,即log₂8=3)。
  • 内层for循环:每次外层循环对应的内层执行次数等于当前i的值,总执行次数是等比数列求和:1 + 2 + 4 + ... + 2^k,其中2^k < n ≤ 2^(k+1)。求和结果为2^(k+1)-1,而2^(k+1) ≤ 2n,因此总操作数为O(n)。
  • 后续while循环:i从首次超过n的值递减到0,其中i < n的部分执行n次赋值操作,总操作数为O(n)。

将各部分相加,总时间复杂度为O(n) + O(n) = O(n)。

简便解题方法建议

  • 等比数列求和法:遇到循环变量翻倍/减半的场景,直接用等比数列求和公式计算总操作数,避免错误的“每次执行次数×循环次数”误区;
  • 分阶段拆解:把算法拆分为多个独立阶段(如本例的求和阶段、归一化阶段),分别计算每个阶段的时间复杂度后再合并;
  • 边界值验证:用小的n值(如n=4、n=8)手动计算循环执行次数,验证复杂度推导是否正确。

算法优化建议

原算法的求和阶段存在大量重复计算(每次内层循环都重新累加前i个元素),可以直接一次遍历完成求和,优化后代码如下:

public float[] normalize(float[] seq) {
    int n = seq.length;
    if (n == 0) return new float[0];
    
    float sum = 0;
    // 一次遍历完成求和,时间复杂度O(n)
    for (float num : seq) {
        sum += num;
    }
    // 避免除以0的边界情况
    float factor = sum != 0 ? n / sum : 0;
    
    float[] res = new float[n];
    for (int i = 0; i < n; i++) {
        res[i] = seq[i] * factor;
    }
    return res;
}

优化后的算法时间复杂度仍为O(n),减少了重复计算,代码可读性更高,同时处理了sum为0的异常情况。


内容的提问来源于stack exchange,提问作者Brogrammer31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:57:51