我坚持使用hackerrank上的圆形阵列旋转算法,但是出现超时问题并且无法提高效率。
我正在使用javascript:
function processData(input) {
var arr = new Array(4);
var arrInt = [];
var n, k, q, index, temp;
arr = input.split(" ", 3); //input is a string, get n,k,q from this
arrInt = input.split("\n");
n = parseInt(arr[0]);
k = parseInt(arr[1]);
q = parseInt(arr[2]);
var arrIntI = new Array(n);
arrIntI = arrInt[1].match(/\d+/g); //read in integer array
arrInt.shift();
arrInt.shift();
for(i = 0; i < k; i++){ //rotate array k times
arrIntI.unshift(arrIntI.pop()); //Timeout on cases: 5, 9, 10, 12, 13, 14; passes all others!!!!!!
//********************** Manual rotation:
//Timeout on cases: 5, 7, 9, 10, 12, 13, 14; Worse that Pop/unshift!!
//temp = arrIntI[n-1];
//for(l = n; l > 0; l--){
// arrIntI[l] = arrIntI[l - 1];
//}
//arrIntI[0] = temp;
//delete arrIntI[n];
//*******************************
}
for(j = 0; j < q; j++){
index = arrInt[j];
console.log(arrIntI[index]);
}
}
process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function (input) {
_input += input;
});
process.stdin.on("end", function () {
processData(_input);
});
我尝试更换unshift / pop以使用for循环旋转数组,但它没有帮助超时的情况。
提前致谢!!
答案 0 :(得分:3)
您根本不需要实际旋转数组,只需使用索引即可计算所有内容。
function int(v){ return v|0 }
function processData(input) {
//parse input string
var rows = input.split("\n");
var values = rows[1].split(" ");
var [n,k,q] = rows[0].split(" ").map( int );
//a minimal validation of the input string
if(values.length !== n || rows.length-2 !== q)
throw new Error("inconsistent imput");
//compute a positive offset
var offset = n - k%n;
//the requested indices start in row 3 (index 2)
return rows.slice(2)
//compute the offset positions, and return the particular values
.map(m => values[ ( int(m) + offset )%n ])
.join("\n")
}
修改:抱歉,我解释一下有点晚了。
首先,想象一下你有一个时钟(其中一个经典的圆形手掌就可以了),然后你就可以获得优异的效果:&#34;将时钟上的数字旋转到左边5个小时,然后告诉我数字是在1,3和6点的位置?&#34; 你怎么做的?你会开始拆卸时钟,然后5次将每个第一个位置向左移动吗? 我打赌你根本不接触这些数字,而只是对自己说:&#34;向左旋转5个小时,然后每个位置显示询问位置右边的5个索引&#34;,当你被问到特定索引的实际数字时,你会去索引3,例如,添加5个索引,并告诉你在该位置读取的数字。
这是如何运作的。我只需添加询问的索引和偏移量,然后返回该位置的值。
现在是否清楚,这是如何运作的?
答案 1 :(得分:0)
据我所知,以下是最快的阵列旋转器。它按提供的量(n)和方向(+/-)
旋转数组Array.prototype.rotate = function(n){
var len = this.length;
if (n % len === 0) return this.slice();
else for (var i = 0, res = Array(this.length); i < len; i++) res[i] = this[(i + (len + n % len)) % len];
return res;
};
答案 2 :(得分:0)
function rotation (arrData, position) {
var newArr = arrData.slice();
var arrLen = newArr.length;
var num = (position < 0)
? arrLen-(position%arrLen)
: position%arrLen;
var tempArr = newArr.splice(0, num);
newArr.push.apply(newArr, tempArr);
return newArr;
}
它将根据输入
旋转var a = [11,2,3,4,5];
rotation(a, 42); // [3, 4, 5, 11, 2]
在超时情况下它也能很好地工作。
希望这有帮助!谢谢 工作示例:http://jsbin.com/rahidox/edit?html,js,console
答案 3 :(得分:0)
function circularArrayRotation(a, k, queries) {
let y;
let x=[]
for (let i = 0; i < k; i++) {
y = a.pop()
a.unshift(y) // no timeout issue, might be a bit longer but it works.
}
for(let j = 0; j < queries.length; j++) {
x.push(a[(queries[j])])
}
return x
}