JavaScript|LeetCode|搜索|78.子集

法1
想法:

  1. 结果集 = 当前元素 + 当前元素与之后剩余元素的子集的组合 + []
  2. 陷阱:“当前元素与之后剩余元素的子集的组合”:当前元素应该与之后剩余元素的真子集组合,否则会出现重复组合(和空子集组合时)
/** 
* @param {number[]} nums 
* @return {number[][]} 
*/
var subsets = function(nums) {    
    var i = 0, j = 0, temp = [], tmp = [], output = [];    
    for(i = 0; i < nums.length; i++) {        
        temp[0] = nums[i];        
        output.push(temp.concat([]));        
        tmp = realSubsets(nums.slice(i + 1));        
        for(j = 0; j < tmp.length; j++) {            
            output.push(temp.concat(tmp[j]));        
        }    
    }    
    output.push([]);    
    return output;
};

function realSubsets(nums) {    
    var i = 0, j = 0, temp = [], tmp = [], output = [];    
    for(i = 0; i < nums.length; i++) {        
        temp[0] = nums[i];        
        output.push(temp.concat([]));        
        tmp = realSubsets(nums.slice(i + 1));        
        for(j = 0; j < tmp.length; j++) {            
            output.push(temp.concat(tmp[j]));        
        }    
    }    
    return output;
}

法2
看了答案
想法:

  1. 遇到一个元素,将它加入结果集
  2. 遇到第二个元素,将它加入结果集(预先在结果集中加入[],那么该元素与空集衔接就是它本身);并将它与结果集合中其他子集衔接组成新的子集。
/** 
* @param {number[]} nums 
* @return {number[][]} 
*/
var subsets = function(nums) {    
    var i = 0, j = 0, length = 0, temp = [], output = [];    
    output.push([]); // output中,空集也是子集之一    
    for(i = 0; i < nums.length; i++) {        
        temp[0] = nums[i];        
        length = output.length; // 将temp与output中当前子集衔接,并加入output        
        for(j = 0; j < length; j++) {            
            output.push(output[j].concat(temp));        
        }    
    }    
    return output;
};

法3:回溯
看了答案
想法:

  1. 以子集的长度(包含元素的个数)为结束条件
/** 
* @param {number[]} nums 
* @return {number[][]} 
*/
var subsets = function(nums) {    
    var k = 0, temp = [], output = [];    
    for(k = 0; k <= nums.length; k++) { // 子集长度由0到nums.length        
        backtrack(nums, temp, k, output);    
    }    
    return output;
};

function backtrack(nums, temp, k, output) {    
    if(temp.length == k) {        
        output.push(temp.concat([]));    
    }    
    var i = 0;    
    for(i = 0; i < nums.length; i++) {        
        temp.push(nums[i]);        
        backtrack(nums.slice(i + 1), temp, k, output);        
        temp.pop();    
    }
}

法4:二进制数/01串
看了答案
想法:

  1. 用01串表示nums中对应位置数字是否存在:0表示不存在,1表示存在。若存在则将其加入temp(nums的子集之一),最后将temp加入output
  2. 一个01串表示一种状态,即一个子集
/** 
* @param {number[]} nums 
* @return {number[][]} 
*/
var subsets = function(nums) {    
    var i = 0, j = 0, temp = [], output = [], state = "";    
    for(i = Math.pow(2, nums.length); i < Math.pow(2, nums.length + 1); i++) {        
        state = i.toString(2).slice(1);        
        for(j = 0; j < state.length; j++) {            
            if(state[j] == '1') {                
                temp.push(nums[j]);            
            }        
        }        
        output.push(temp.concat([]));        
        temp = [];    
    }    
    return output;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值