全排列
给定N个数,如 [1,2,3,4,5]
,获取它的全排列
经典交换算法
核心思路是交换
#include<stdio.h>
void swap(int* a, int* b){
int temp = *a;
*a = *b;
*b = temp;
}
//int a[] = { 1,2,3,4};
//sort(a, 0, 4);
void sort(int* a, int k, int m){
if (k == m){
int i = 0;
for (; i < m; i++){
printf("%d", a[i]);
}
}else{
int j = k;
for (; j < m; j++){
swap(&a[k], &a[j]);
sort(a, k + 1, m);
swap(&a[k], &a[j]);
}
printf("\n");
}
}
// 上述代码的js版本
let arr = [1, 2, 3, 4];
let res = []
function sort(arr, k) {
if (k === arr.length) return res.push(arr);
for (let a = k; a < arr.length; a++) {
let arr1 = [...arr];
let t = arr1[k];
arr1[k] = arr1[a];
arr1[a] = t;
sort(arr1, k + 1)
}
}
sort(arr, 0, 4);
console.log(res)
动态规划 DP
有图有真相 ,把每次方法的返回值作为数组一部分递归调用。
function dp(arr) {
if (arr.length === 1) {
return arr;
}
let r = [];
for (let a = 0; a < arr.length; a++) {
let arr1 = [...arr];
let v = arr1[a];
arr1.splice(a, 1);
dp(arr1).forEach(e => {
let t = []
t = t.concat(e, v)
r.push(t)
})
}
return r;
}
元素移动
定义两个数组,源数组和目标数组,从源不停的往目标移动,源空了
就代表生成了一个排列。
// 全排列,移动算法 从源数组不停的向目标数组移动,直到源数组拿空
function range(list) {
let r = [];
function move(src, dist) {
if (!src.length) {
return r.push(dist)
}
src.forEach((v, i) => {
// 复制一份源数组,删除第i个
let s = [...src];
s.splice(i, 1)
// 把第i个放到目标数组中
let d = [...dist, v]
move(s, d)
})
}
move(list, [])
return r;
}