js-challenges
js-challenges copied to clipboard
产生一个不重复的随机数组
// 参数 数组长度、最小范围、最大范围
function randomUniqueArr(len = 100, min = 0, max = 200) {
if (max - min < len) {
// 可生成数的范围小于数组长度
return null;
}
const hash = [];
while (hash.length < len) {
const num = Math.floor(Math.random() * max);
if (num < min) continue;
if (hash.indexOf(num) === -1) {
hash.push(num);
}
}
return hash;
}
console.log(randomUniqueArr());
console.log(randomUniqueArr(20, 10, 31));
function randomUniqueArr(len, min, max) {
if (!len || len <= 0) return []
const _min = Math.min(min, max);
const _max = Math.max(min, max);
if (!(_max - _min)) return [_max];
if (len >= _max - _min) return new Array(_max - _min + 1).fill(null).map((_, idx) => idx + _min);
const set = new Set();
while (set.size < len) {
set.add(~~(Math.random() * _max) + _min);
}
return [...set];
}
const a = randomUniqueArr(100, 10000, 100000000);
const b = randomUniqueArr(100, 1, 50);
const c = randomUniqueArr()
const d = randomUniqueArr(100, 100, 100)
console.log(a, a.length);
console.log(b, b.length);
console.log(c, c.length);
console.log(d, d.length);
// 1. 简单版数组乱序
function generateRandomV1(num) {
return num.sort(() => Math.random() - 0.5);
}
// 2. 复杂版
function generateRandom(len = 10, min = 1, max = 30) {
if (max - min < len) return null;
const hash = [];
while (hash.length < len) {
const num = Math.floor(Math.random() * max);
if (num < min) continue;
if (hash.indexOf(num) === -1) hash.push(num);
}
return hash;
}
const res = generateRandom();
console.log(res);
function randomUniqueArr(len: number, min: number, max: number) {
if (max - min + 1 < len) {
return null;
}
const hash: number[] = [];
while (hash.length < len) {
const num = Math.round(Math.random() * (max - min)) + min;
if (!hash.includes(num)) {
hash.push(num);
}
}
return hash;
}
注意点:
- 判断是否包含数量应该是
max - min + 1 < num
, 比如 1 和 2 之间是可以选中两个的 - 取值用
Math.round
保证可以取到最大值和最小值
function fn(max, min, len, set = new Set()) {
if (max - min < len) throw new Error("len 超过了取值范围");
while (set.size < len) {
set.add(Math.ceil(Math.random() * (max - min) + min));
}
return [...set];
}
function curry(fn) {
const target = arguments[0];
let args = Array.prototype.slice.call(arguments, 1);
return function () {
args.push(...arguments);
if (args.length < fn.length) {
return arguments.callee;
} else {
return target(...args);
}
};
}
let fnn = curry(fn, 10, 5);
let fnnn = curry(fn, 20, 15);
let fnnnn = curry(fn, 30, 25);
let fnnnnn = curry(fn, 40, 5);
console.dir(fnn(5));
console.dir(fnnn(5));
console.dir(fnnnn(5));
console.dir(fnnnnn(35));
const randomUniqueArr = (len, min, max) => {
// min、max 是可以获取到的
if (max - min < len - 2) {
return []
}
const set = new Set()
while (set.size < len) {
// 取值用 Math.round 保证可以取到最大值和最小值
const num = Math.round(Math.random() * (max - min)) + min;
set.add(num)
}
return [...set]
}
const res = randomUniqueArr(2, 2, 3)
function random(len = 10, min = 0, max = 200) {
if (max < min) {
throw new Error("max must greater hhan or equalTo min!");
}
if (max - min + 1 < len) {
throw new Error(
"len must greater hhan or equalTo the sum of min and max !"
);
}
const numbers = new Set();
while (len !== numbers.size) {
const num = Math.floor(Math.random() * (max - min) + min);
numbers.add(num);
}
return [...numbers];
}
//返回一个两数之间的随机整数[min max]
function getRandomIntInclusive(min, max) {
var _min = Math.ceil(Math.min(min, max));
var _max = Math.floor(Math.max(min, max));
return Math.floor((Math.random() * (_max - _min + 1) + _min));
}
//返回目标数组 len 数组长度 min max 随机数区间
function randomUniqueArr(len, min, max) {
//防止数组长度大于随机区间
if (len > Math.abs(max - min + 1))
return '数组长度大于随机区间,无法产生一个不重复的随机数组';
var arr = [];
while (arr.length < len) {
var ran = getRandomIntInclusive(min, max);
if (arr.indexOf(ran) == -1)
// arr[arr.length] = ren;
arr.push(ran);
}
return arr;
}
var arr1 = randomUniqueArr(20, 20, 50);
var arr2 = randomUniqueArr(20, 21, 40);
var arr3 = randomUniqueArr(20, 20, 30);
console.log(arr1);
console.log(arr2);
console.log(arr2.sort());
console.log(arr3);
//注意Math.random()的随机区间[0 1)
//输入的数据 数组长度不能大于随机区间
function randomUniqueArr(len, min = 0, max = 10) { let arr = [] while (arr.length < len) { let num = Math.floor(Math.random() * (max - min + 1) + min) if (arr.indexOf(num) === -1) { arr.push(num) } } return arr }
时间复杂度为 O(n)
经典算法 Fisher-Yates
function generateRandomArray(length) {
let arr = [];
for (let i = 1; i <= length; i++) {
arr.push(i);
}
// Fisher-Yates算法
for (let i = arr.length - 1; i > 0; i--) {
const randomIndex = Math.floor(Math.random() * (i + 1));
[arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
}
return arr;
}
const arr = generateRandomArray(10);
console.log(arr);
时间复杂度为 O(n) 经典算法 Fisher-Yates
function generateRandomArray(length) { let arr = []; for (let i = 1; i <= length; i++) { arr.push(i); } // Fisher-Yates算法 for (let i = arr.length - 1; i > 0; i--) { const randomIndex = Math.floor(Math.random() * (i + 1)); [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]]; } return arr; } const arr = generateRandomArray(10); console.log(arr);
function generateRandomArray(len, min, max) {
const range = Array.from({length: max - min + 1}, (_, index) => index + min);
for (let i = range.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[range[i], range[j]] = [range[j], range[i]];
}
const result = range.slice(0, len);
return result;
}
const len = 100;
const min = 0;
const max = 200;
const randomArray = generateRandomArray(len, min, max);
console.log(randomArray);
// 参数 数组长度、最小范围、最大范围
function randomUniqueArr(len, max, min) {
if (max - min < len) return [];
const result = [];
while (result.length < len) {
let num = Math.round(Math.random() * (max - min) + min);
if (!result.includes(num)) {
result.push(num);
}
}
return result;
}
function randomUniqueArr(len: number, min: number, max: number): number[] {
if (max - min < len) throw Error("out of bounds");
return Array(max + 1 - min)
.fill(max)
.map((max, i) => max - i)
.sort(() => Math.random() - 0.5)
.slice(0, len);
}