当前位置: 首页 > Web前端 > HTML

前端电商sku的全数组算法

时间:2023-03-29 11:13:05 HTML

描述起来非常简单。共有三个数组:letnames=["iPhone",'iPhonexs']letcolors=['black','white']letstorages=['64g','256g']需要穷举它们的所有组合,最后得到这样一个数组:[["iPhoneX","black","64g"],["iPhoneX","black","256g"],["iPhoneX","white","64g""],["iPhoneX","白色","256g"],["iPhoneXS","黑色","64g"],["iPhoneXS","黑色","256g"],["iPhoneXS","white","64g"],["iPhoneXS","white","256g"],]由于这些属性数组是不确定的,所以我们不能简单的用三重暴力循环来解决问题.如果我们使用递归回溯的方法来解决这个问题,那么最重要的问题就是设计我们的递归函数来分解上面提到的思想。举个例子,比如我们当前的属性数组是names、colors、storages。首先,我们将处理名称数组。显然,对于每一个属性数组,我们都需要遍历它,逐一选择,然后再去到下一个数组的每一项。组合我们设计的递归函数接收两个参数index对应当前正在处理的下标,无论是names,colors还是storage。prev上次递归拼接的结果,如['iphoneX','black'],进入递归函数:处理属性数组的下标0:假设我们在第一次循环中选择iphoneXS,则我们有一个未完成Thecompleted结果状态,假设我们称它为prev,此时prev=['iphoneXs']。处理属性数组的下标1:那么我们就处理完了colors数组,有了prev。遍历colors时,继续递归地将prev拼接成prev.concat(color),即['iphoneXs','Black'],这样,继续将这个prev交给下一个递归处理属性数组的下标2:然后处理storages数组得到name+color的prev,在遍历storages时继续递归拼接prev进入prev.concat(storage)即['iPhoneXS','black','64g'],此时我们发现处理后的属性数组下标已经到了尾部,于是将其放入全局结果变量res中,结果编码实现letnames=['iphoneX',"iPhoneXS"]letcolors=['black','white']letstorages=['64g','256g']letcombine=function(...chunks){letres=[]lethelper=function(chunkIndex,prev){letchunk=chunks[chunkIndex]letisLast=chunkIndex===chunks.length-1for(letvalofchunk){letcur=prev.concat(val)//['iphoneX','black','64g'],['iphoneX','black','256g'],['iphoneX','white','64g']if(isLast){//如果数组最后一项处理完毕,将拼接结果放入返回值res.push(cur)}else{helper(chunkIndex+1,cur)}}}//从属性数组下标从0开始处理//此时prev是一个空数组helper(0,[])returnres}console.log(combine(names,colors,storages));["iphoneX","black","64g"]["iphoneX","black","256g"]["iphoneX","白色","64g"]["iphoneX","白色","256g"]["iPhoneXS","黑色","64g"]["iPhoneXS","黑色","256g"]["iPhoneXS","White","64g"]["iPhoneXS","White","256g"]通用模板给定两个整数n和k,返回所有1...n可能k个数字的组合输入:n=4,k=2输出:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]Answerletcombine=function(n,k){letret=[]lethelper=(start,prev)=>{letlen=prev.lengthif(len===k){ret.push(prev)返回//[[1,2]]}for(leti=start;i<=n;i++){helper(i+1,prev.concat(i))//helper(2,[1])[1,2]//助手(3,[1]),[1,3]//助手(4,[1])[1,4]//助手(3,[2])[2,3]//helper(4,[2])[2,4]//helper(4,[3])[3,4]}}helper(1,[])returnret}可以看到这个了问题与我们解决电子商务排列组合的代码非常相似。我们只需要设计一个接受开始排列的开始位置。prev的最后一个拼接结果是参数的递归辅助函数then对于每个起始点下标start,先拼接起始位置对应的值,然后继续以剩下的其他下标为起始点做下一次拼接当prev中间状态的拼接数组达到title要求的长度k时,会放入result数组进行优化。在这个解决方案中,有一些递归分支显然是不可能得到结果的。我们将每次循环遍历所有<=n的递归。itemasstart假设我们要求的数组长度为k=3,最大值n=4,我们用prev=[1],然后用n=4作为递归的起点,显然是不可能的得到结果,因为如果n=4,就只剩4个可以拼接了,最多可以拼接成[1,4]。不可能满足k=3的条件,所以在进入递归之前,果断减去这些废枝。这叫做分支缩减letcombine=function(n,k){letret=[]lethelper=(start,prev)=>{letlen=prev.lengthif(len===k){ret.push(prev)return}//还有剩余的位置需要填充letrest=k-prev.lengthfor(leti=start;i<=n;i++){if(n-i+1{//0,[],2if(prev.length===target){letkey=genKey(prev)if(!used[key]){res.push(prev)used[key]=true}return}for(leti=start;i<=n;i++){letrest=n-iletneed=target-prev.lengthif(rest1~2~7/***@param{number[]}candidates*@param{number}target*@返回{number[][]}*/letcombinationSum2=function(candidates,target){letres=[]if(!candidates.length){returnres}candidates.sort()letused={}lethelper=(start,prevSum,prevArr)=>{//因为都是正整数,一旦和大于目标值,就结束本次递归if(prevSUm>target){return}//达到目标值if(prevSum===target){letkey=genkey(prevArr)if(!used[key]){res.push(prevArr)used[key]=true}return}for(leti=start;iarr。加入('?')