比如 123 这个数字
重新组合成
1
2
3
12
13
23
21
31
32
321
...
怎么实现呢,思路,谢谢
function combine(num){
num +='X';
var nums=num.split("");
var arr=[];
var tmp="";
var len = nums.length;
var dfs = function(a){
for(var i=0;i<a.length;i++){
if(a[i]=='X'){
if(tmp)
arr.push(tmp);
continue;
}
var cut=a.splice(i,1)[0];
tmp+=cut;
dfs(a);
a.splice(i,0,cut);
tmp=tmp.substr(0,tmp.length-1);
}
}
dfs(nums);
return arr;
}
深度遍历,看不懂的私信我
举个例子,比如三位数的数字,
1.先找到所有1位数的组合,然后再进行排列
2.找出所有两位数的组合,再排列
3.找到三位数的组合,再排列
然后将三类结果综合起来,就是想要结果
看了下上面的解答,我给个c++的。
首先这个题目,一眼看过去什么都不用想,绝对递归!!!
mskf朋友的深搜,我看不懂php,所以不知道对不对,但用的都是递归。
我参照按照treeandgrass这位朋友的思路。
因为这种题,很有规律,所以一个函数就可以搞定。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
/* len:打印的长度;depth:递归的深度 */
void Recursion(int array[], int left, int right, int len, int depth)
{
if (depth == 0)
{
for (int i = 0; i < len; i++)
cout << array[i];
cout << endl;
}
for (int i = left; i <= right; i++)
{
swap(array[i], array[left]);
Recursion(array, left + 1, right, len, depth - 1);
swap(array[i], array[left]);
}
}
int main()
{
int array[5] = { 1,2,3,4,5 };
Recursion(array, 0, 4, 1, 1);
Recursion(array, 0, 4, 2, 2);
Recursion(array, 0, 4, 3, 3);
Recursion(array, 0, 4, 4, 4);
Recursion(array, 0, 4, 5, 5);
return 0;
}
建议LZ先看下这个版本的全排列,再看你这个题目,再看我的代码就懂了。http://blog.csdn.net/laojiu_/article/details/51115352
var replace = (s, idx) => s.slice(0, idx) + s.slice(idx + 1);
// replace('123', 0) -> "23"
// replace('123', 1) -> "13"
// replace('123', 2) -> "12"
var toArr = str => str.trim().split(' ');
// "hello world" -> ["hello", "world"];
// "hello world " -> ["hello", "world"];
利用上面的工具函数 replace
把待处理字符串 str
分为两部分 头
和 剩下的部分
然后递归的处理剩下的部分。
如图 "123" 的头和尾组合是 123
213
312
然后递归的处理尾 23 13 12 得到 (23, 32) 和 (13, 31) 和 (12, 21)
把 1 应用到 23, 32
把 2 应用到 13, 31
把 3 应用到 12, 21
就可以得到 "123" 的全遍历结果 123, 132, 213, 231, 312, 321 共 6 个
因为是递归的处理尾,长度为 n-1
的时候也可以得出 想要的结果。
以下是我的实现
// 需要工具函数 replace
// 利用工具函数 toArr 可以把结果转化成数组
var all = str => {
if (str.length === 1) return str + ' ';
return str.split('').reduce((acc, cur, idx, its) => {
// 子串
var subStr = replace(str, idx);
// 这里相当于 map (+its[idx]) all(subStr).toArray 。。。。
acc += all(subStr).split(' ').map(e => its[idx] + e).join(' ') + ' ';
return acc;
}, '');
}
var a = toArr(all("123"));
var b = toArr(all("12"));
var c = toArr(all("1"));
console.log('a: ', a);
console.log('b: ', b);
console.log('c: ', c);
结果如图
果然受到了 Haskell 影响... 现在看列表和字符串都是 头 + 尾
的结构... 即 x:xs
1 回答3.4k 阅读✓ 已解决
1 回答2.8k 阅读
2.5k 阅读
1 回答544 阅读✓ 已解决
1 回答1.1k 阅读
1 回答514 阅读✓ 已解决
本人使用语言 js, 观 上面数组的 规律, 新数字的 长度 是1-3(包含1 、3) , 数字 不存在123 中任何重复一项,既每一位 都只 取一次。
实现思路 :
1 、声明 一个 num数字 toString下变成字符串 str,获取 str它的长度(举例为3) ;
2 、随机一个1-3 (包含1 、3)数字作为 数组的长度(arrLength) 这个长度既 新数字的位数,
3 、再 从这个 str.substr( Math.random()3 ,1) ,截取一位数字,再将这个数字push 到一个数组中去,arrLength为几 就截取 几次就可以了, 在这里最好用一个循环, Math.random()3 这里的3 下次就会变成2 , 原字符串长度 会发生改变。
4、 截取完成后 得到的新数组arr , 用join(“”)合并一下,继续parserInt 就ok ,完成 了