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

LeetCode子集问题:位运算两种写法为何一个触发内存超限?

子集问题位运算代码内存超限原因分析

我尝试用位运算解决Subsets问题,最初写的代码运行时触发Memory Limit Exceeded错误:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int num=(int)Math.pow(2,nums.length);
        List<List<Integer>> ans = new ArrayList<>();
        for(int i=0;i<num;i++)
        {
          List<Integer> ls = new ArrayList<>();
          int addNum=nums.length-1;
          while(i>0)
          {
            if((i&1)!=0)
            {
               ls.add(nums[addNum]);
            }
            addNum--;
            i=i>>1;
          }
          ans.add(ls);
        }
        return ans;
    }
}

后来看到另一位用户的代码,逻辑类似但用了辅助函数,能正常通过测试:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
       List<List<Integer>> ans=new ArrayList<>();
       int num = (int)Math.pow(2,nums.length);
       for(int i=0;i<num;i++)
       {
         List<Integer> ls = helper(i,nums);
         ans.add(ls);
       }
       return ans;
    }
    public List<Integer> helper(int i, int[] nums)
    {
      List<Integer> ls = new ArrayList<>();
      int j=0;
      while(i>0)
      {
         int rem=i&1;
         if(rem==1)
         {
           ls.add(nums[j]);
         }
         j++;
         i=i>>1;
      }
      return ls;
    }
}

想请教为什么第一段代码会内存超限?


核心原因:循环变量被意外修改导致无限循环

第一段代码的致命问题是在for循环内部直接修改了循环控制变量i:

  • 在while(i>0)循环中,执行i=i>>1会直接改变for循环的控制变量值。
  • 举个典型场景:当i=1时,进入while循环后i会被右移为0,while循环结束。此时for循环的i++会把i变回1,导致for循环永远卡在i=1的状态,无法递增到num。
  • 无限循环会持续创建新的ArrayList并添加到结果集合中,最终耗尽内存,触发Memory Limit Exceeded错误。

而第二段代码通过辅助函数规避了这个问题:

  • 辅助函数的参数i是原循环变量的副本,在helper方法中修改的是这个副本的值,完全不会影响外部for循环的控制变量。
  • for循环能正常从0遍历到num-1,内存使用始终保持在合理范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:44:50