给定一个最小长度为3且最大长度为5的数组,它总是包含从0到4 的唯一出现的整数,我需要选出两个非连续的数字从中。非连续是指它们的数值,而不是它们在数组中的位置。
为了澄清,以下是有效数组的示例:
[ 1, 2, 3 ]
[ 0, 1, 2, 4 ]
[ 0, 3, 4 ]
对于上面的数组,有效答案可分别为:
[ 1, 3 ]
[ 0, 2 ]
,[ 0, 4 ]
或[ 1, 4 ]
[ 0, 3 ]
或[ 0, 4 ]
此外,在有多个有效答案的情况下,如果可能的话,我需要随机选择它(例如我不想支持以最低编号开头的序列,如果我总是从左到右开始检查并在我找到一个有效的解决方案后立即停止检查,那会发生什么。)
在Javascript中解决此问题的最有效方法是什么?
答案 0 :(得分:1)
您可以使用两个嵌套迭代并构建一个新数组,以便选择随机结果。
function getNonConsecutives(array) {
return array.reduce((r, a, i, aa) => r.concat(aa.slice(i + 2).map(b => [a, b])), []);
}
console.log(getNonConsecutives([ 0, 1, 2, 4 ]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
根据Bee157的answer,您可以使用带约束的随机选择,例如第一个索引的长度,并为第二个索引添加所需的空间。
问题是,由于首先选择第一个数字的性质,结果的分布不相等。
function getNonConsecutives(array) {
var i = Math.floor(Math.random() * (array.length - 2));
return [
array[i],
array[Math.floor(Math.random() * (array.length - 2 - i)) + 2 + i]
];
}
console.log(getNonConsecutives([ 0, 1, 2, 4 ]));
答案 1 :(得分:0)
因为您声明数组ellemnts都是唯一的,并且它们已被排序 应该采用随机元素
var index1=Math.floor(Math.random()*arr.length)
现在任何其他元素(除了位置上的元素(index1 +/- 1)都不连续 因此,可以选择一个新的随机元素,排除第一个索引。
var index2=Math.floor(Math.random()*arr.length);
if(index2==index1){
index2+=((index2<arr.length-1)?1:-1);
}
if(Math.abs(arr[index1]-arr[index2])<=1){
if(index2==0 && arr.length<4){
//set index2 to arr.length-1 and do check again, if not ok=> no result
if(!(arr[index1]-arr[arr.length-1]>=-1)){
return [arr[arr.length-1],arr[index1]];
}
}
else if(index2==arr.length-1 && arr.length<4){
//set index2 to 0 and do check again, if not ok=> no result
if(!(arr[index1]-arr[0]<=1)){
return [arr[0],arr[index1]];
}
}
else{
//if index2>index1 index2++
//else index2--
//always OK so no further check needed
index2+=(index2>index1?1:-1);
return [arr[index1],arr[index2]];
}
}
else{
//ok
return [arr[index1,arr[index2]];
}
return false;
如果速度不重要,您可以使用数组上的过滤器来计算一个新数组,其中所有元素的差异超过1个arr [index1]单位。并从这个新数组中随机选择一个新数字。
其他尝试
function getNonConsecutive(arr){
var index1,index2,arr2;
index1=Math.floor(Math.random()*arr.length);
arr2=[].concat(arr);
arr2.splice((index1!==0?index1-1:index1),(index!==0?3:2));
if(arr2.length){
index2=Math.floor(Math.random()*arr2.length);
return [arr[index1],arr2[index2]];
}
else{
//original array has length 3 or less
arr2=[].concat(arr);
arr2.splice(index1),1);
for (var j=0,len=arr.length;j<len;j++){
if(Math.abs(arr1[index1]-arr2[j])>1){
return [arr[index1],arr2[j]];
}
}
}
return false
}
答案 2 :(得分:0)
这样的事情应该这样做:
const pick = nums => {
// Pick a random number
const val = nums[Math.floor(Math.random() * nums.length) + 0];
// Filter out any numbers that are numerically consecutive
const pool = nums.filter(n => Math.abs(n - val) > 1);
// Pick another random number from the remainer
const other = pool[Math.floor(Math.random() * pool.length) + 0];
// Sort + return them
return [val, other].sort();
};
console.log(pick([0, 1, 2, 4]));
答案 3 :(得分:0)
demoFn(array) {
var i,j, y =[];
for (i=0; i<=array.length;i++) {
for (j = i + 1; j <= array.length; j++) {
if (array[j] && array[i]) {
if (array[j] !== array[i] + 1) {
y.push([array[i], array[j]]);
}
}
}
}
}
随机排列并检查它。
答案 4 :(得分:0)
您可以使用递归创建一个函数,该递归将在每次迭代中选择随机数并循环所有其他元素,如果满足条件则添加到数组。
function findN(data) {
data = data.slice();
var r = []
function repeat(data) {
if (data.length < 2) return r;
var n = parseInt(Math.random() * data.length);
data.forEach(function(e, i) {
if (i != n) {
var a = data[n];
if (Math.abs(a - e) != 1 && r.length < 2) r.push(n < i ? [a, e] : [e, a])
}
})
data.splice(n, 1);
repeat(data)
return r;
}
return repeat(data)
}
console.log(findN([1, 2, 3]))
console.log(findN([0, 1, 2, 4]))
console.log(findN([0, 3, 4]))
&#13;