Leetcode Rotate Array works differently in codepen [duplicate] - javascript

This question already has answers here:
Rotate the elements in an array in JavaScript
(42 answers)
Closed 2 months ago.
I've solved one of Leetcode problems in codepen, but when I try to submit it on leetcode I get a different result than what I get in codepen.
The problem is:
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
Link (requires login) https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/646/
My solution:
var rotate = function(nums, k) {
var a = nums.splice(0 , nums.length-k);
var b = nums.splice(-k);
var c = [...b , ...a ];
return(c);
};
Using the above example, running this code on codepen returns (or console.logs) [5,6,7,1,2,3,4].
But when I run this code in leetcode, I get an empty array [].
Any ideas why this could be the happening?

It looks like you're supposed to rotate the original array, not return a new rotated array. So you need to set nums = [...b, ...a] instead.
EDIT: Since JavaScript passes by value, the nums parameter just holds a reference to the original array, so doing nums = [] will only change the nums variable to reference a different array, without changing the original array. You'll want to call methods of the original array to mutate it. E.g. .splice
/EDIT
Also, have you thought about what happens when k is greater than the length of the array? E.g. nums = [1, 2, 3], k = 5
Also also, your link to leetcode requires login, so not everyone will be able to view it.

Example A
.pop() removes the last element of an array and returns it. .unshift() the returned value of .pop() to the first index of the array. Do that k times in a for loop. .pop() and .unshift() changes (aka mutates) the original array.
let arr = [1, 2, 3, 4, 5, 6, 7], k = 3;
function rotate(array, times) {
for (let i=0; i < times; i++) {
let last = array.pop();
array.unshift(last);
}
return array;
}
console.log(rotate(arr, k));
Example B
By changing .splice() to .slice() you can implement your logic since .slice() creates a shallow copy of the array and does not mutate the original array like .splice(). Since the original array is unchanged, any references to said array are consistent. Also, concerning the case mentioned in LawrenceWebDev's answer -- if k is greater than the length of the array -- k (times) becomes the remainder of k/array.length (times % size).
let arr = [1, 2, 3, 4, 5, 6, 7], k = 3;
function rotate(array, times) {
const size = array.length;
if (times > size) {
times = times % size;
}
let a = array.slice(-times);
let b = array.slice(0, size - times);
return [...a, ...b];
}
console.log(rotate(arr, k));

Related

Spinning the elements of an array clockwise in JS

I am supposed to rotate an array of integers clockwise in JS.
Here is my code for it:
function rotateArray(N, NArray)
{
//write your Logic here:
for(j=0;j<2;j++){
var temp=NArray[N-1];
for(i=0;i<N-1;i++){
NArray[i+1]=NArray[i];
}
NArray[0]=temp;
}
return NArray;
}
// INPUT [uncomment & modify if required]
var N = gets();
var NArray = new Array(N);
var temp = gets();
NArray = temp.split(' ').map(function(item) { return parseInt(item, 10);});
// OUTPUT [uncomment & modify if required]
console.log(rotateArray(N, NArray));
The code accepts an integer N which is the length of the array. The input is as follows:
4
1 2 3 4
The correct answer for this case is supposed to be
4 1 2 3
But my code returns
4 1 1 1
I cannot find where my code is going wrong. Please help me out.
All you need to do is move one item from the end of the array to the beginning. This is very simple to accomplish with .pop() (removes an item from the end of an array), then declare a new array with that element as the first:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem, ...NArray];
}
console.log(rotateArray(1, [1, 2, 3, 4]));
Doing anything else, like using nested loops, will make things more unnecessarily complicated (and buggy) than they need to be.
If you don't want to use spread syntax, you can use concat instead, to join the lastItem with the NArray:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem].concat(NArray);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
If you aren't allowed to use .pop, then look up the last element of the array by accessing the array's [length - 1] property, and take all elements before the last element with .slice (which creates a sub portion of the array from two indicies - here, from indicies 0 to the next-to-last element):
function rotateArray(N, NArray) {
const lastItem = NArray[NArray.length - 1];
const firstItems = NArray.slice(0, NArray.length - 1);
return [lastItem].concat(firstItems);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
function rotate(array,n){
Math.abs(n)>array.length?n=n%array.length:n;
if(n<0){
n=Math.abs(n)
return array.slice(n,array.length).concat(array.slice(0,n));
}else{
return array.slice(n-1,array.length).concat(array.slice(0,n-1));
}
}
console.log(rotate([1, 2, 3, 4, 5],-3));
The answer by #CertainPerformance is great but there's a simpler way to achieve this. Just combine pop with unshift.
let a = [1,2,3,4];
a?.length && a.unshift(a.pop());
console.log(a);
You need to check the length first so you don't end up with [undefined] if you start with an empty array.

Filtering an array and converting it to a 2D array

I saw this interesting post yesterday, and thought it'd be important to know how to create a 2D array from sorting the given argument:
How to get even numbers array to print first instead of odds?
Below is the code snippet from Ori Drori.
I was curious to know what line of code, and which expression sorts the data and creates 2D array. I assume it's something to do with [numbersArray[i] % 2], but isn't the remainder operator returns the remainder left over?
Also it's a bit confusing as it just set one bracket for an array and use push() to make 2 different arrays.
Any reference that'd help me to understand this will also be much appreciated- thanks!
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[numbersArray[i] % 2].push(numbersArray[i]);
}
return evensOdds;
}
console.log(divider(numbersArray));
evensOdds has 2 array elements. evensOdds[0] represents first array, which will hold even nums. evensOdds[1] is second element and will hold odd numbers.
When you % 2 an even number, it will result in 0 and 1 for odd number. So when iterating through the array, you % 2, which will return 0 or 1 which enables you to access the first or second array in your evensOdds array and insert it.
The resulting arrays are not sorted but does represent the split between even and odd numbers. To have a sorted results, you will need the following:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[numbersArray[i] % 2].push(numbersArray[i]);
}
return evensOdds.map(array=> array.sort((a,b)=>a-b));
}
console.log(divider(numbersArray));
In the shared code the evensOdds[numbersArray[i] % 2] line is the part that filter the numbers and inserts them in the respective array, using the indexes 0 and 1 returned from the numbersArray[i] % 2 expression:
If it returns 0 so it's an even number and it will be pushed in the first array otherwise if it returns 1 it's an odd number and will be pushed in the second array.
Another alternative:
Well you can simply use Array.filter() method to filter both evens and odds arrays:
Demo:
var numbersArray = [1, 2, 34, 54, 55, 34, 32, 11, 19, 17, 54, 66, 13];
var evens = numbersArray.filter(function(el) {
return el % 2 == 0;
});
var odds = numbersArray.filter(function(el) {
return el % 2 == 1;
});
console.log(evens);
console.log(odds);

Shorter way to remove an item by index from an array [duplicate]

This question already has answers here:
How to delete an item from state array?
(18 answers)
Closed 5 years ago.
I've made this post last year and today, I assume things can be simplified.
I need to remove an item from an array but by the index. When by the index, it does not matter if the array has same values. Your typical example:
let arr = [1,2,3,2,1] // just an array, not array with objects
let x = 1;
// This will not be an expected result:
// Find all values that is equal to 1 then remove
arr.filter(num => num !== x) //=> [2,3,2]
My expectation is when I remove the last element (1), for example, the array should be [1,2,3,2]:
let index = 4; // which is the last "1" in the array
let indexVal = arr.indexOf(4) // 1
let newArray = arr.splice(indexVal, 1) //=> [1,2,3,2]
Now, it's 2017, almost '18, is there a shorter way (es5/6) of doing this without any polyfil?
Edit:
Think of this as a todo:
<ul>
<li>me</li>
<li>me</li> // click to delete this one
<li>you</li>
<li>me</li>
</ul>
To correctly remove that item, I have to delete by the index not value
The Array.filter callback gives 2 arguments, number and index and you can filter the array this way.
let arr = [1,2,3,2,1]
let x = 4; //suppose you want to remove element at 4th index
let editedArray = arr.filter((num, index) => index !== x) //editedArray = [1,2,3,2]
EDIT:
The third parameter gives the whole array. Thanks #Oliver for pointing this out in comment
arr.splice(index, 1);
or if you specifically want to remove the last element:
arr.pop();
No indexOf call. The indexOf call never should have been there; it only ever looked like it worked because indexOf returns -1 for an element that isn't present, and splice treats negative indices as counting from the end of the array.
Also, splice modifies the array in place and returns an array of removed elements, so assigning its return value the way you were doing is misleading.
The only way I can think of is the one we use in Redux every day:
const arr = [1, 2, 3, 2, 1]
const index = 4 // index of the item you want to remove
const newArr = [...arr.slice(0, index), ...arr.slice(index + 1)]
console.log(newArr) // [1, 2, 3, 2]
It might not be the shortest but it is more 2017 and it is immutable, which is very important!
Ajay's answer might be what you're looking for. Anyway, there are people like me who prefer slightly-more-lines-but-more-readable/rewritable/maintable solution, I'd do it this way:
function removeElementByIndex(arr, x) {
var newArr = [];
for(var i = 0; i < arr.length; i++) {
if(i != x) {
newArr.push(arr[i]);
}
}
return newArr;
}
// Usage
removeElementByIndex([1, 2, 3, 2, 1], 4);// outputs: [1, 2, 3, 2]
Now, it's 2017, almost '18, is there a shorter way (es5/6) of doing
this without any polyfil?
LOL! Many basic things not yet implemented. We'll have to wait for 2118 or another programming language to replace JS (oh wait, there's one, aka jQuery :P ).

Javascript tracking the differences between elements in an array?

I have the following simple array:
my_array = [1, 11, 44, 4]
I want to produce a new array consisting of the difference between these elements, so it would be:
diff_array = [10, 33, 40]
What's the best way of going about this?
You could use Array#reduce for iterating and take the absolute delta for pushing to the result array.
Basically you need array.length - 1 deltas and iteration. In this case 3. Reduce takes, if no start value is given, the first two elements and iterates the wanted length. And while it needs the last value for the delta, the last value is returned.
At the end, the returned value of reduce is discarded, becuase it is not used anymore.
1 11 44 4 values
\ / \ / \ /
10 33 40 Math.abs(delta)
var array = [1, 11, 44, 4],
result = [];
array.reduce(function (a, b) {
result.push(Math.abs(a - b));
return b;
});
console.log(result);
here is a simple solution with a plain old for loop
array = [1, 11, 44, 4]
diff = []
for(var i = 1 ; i < array.length ; i++){
diff.push(Math.abs(array[i] - array[i-1]))
}
basically you loop starting at the second element of the array ,, and subtract from from the prev and pushing to the new array .
use this function, pass it the input array, returns the required array.
function diff(array){
var out = []
for (var i = 0; i < array.length-1; i++) {
out.push(Math.abs(array[i+1]-array[i]))
}
return out;
}
Normally one can do this with .reduce() but just for fun lets get some functional.
var myArray = [1, 11, 44, 4],
diff = a => a.length > 1 ? [Math.abs(a[1]-a[0])].concat(diff(a.slice(1))) : [];
console.log(diff(myArray));
Note: The above code is just for demonstration purposes. In your daily JS life you shouldn't do things like this. Use a whatever loop you like but never use recursion in your JS code. You want to see what i mean? Feed this array.
var myArray = Array(1000000).fill().map(_ => ~~(Math.random()*100+1));
It will beautifully crash your browser's tab. Peah..!

Duplicate an array an arbitrary number of times (javascript)

Let's say I'm given an array. The length of this array is 3, and has 3 elements:
var array = ['1','2','3'];
Eventually I will need to check if this array is equal to an array with the same elements, but just twice now. My new array is:
var newArray = ['1','2','3','1','2','3'];
I know I can use array.splice() to duplicate an array, but how can I duplicate it an unknown amount of times? Basically what I want is something that would have the effect of
var dupeArray = array*2;
const duplicateArr = (arr, times) =>
Array(times)
.fill([...arr])
.reduce((a, b) => a.concat(b));
This should work. It creates a new array with a size of how many times you want to duplicate it. It fills it with copies of the array. Then it uses reduce to join all the arrays into a single array.
The simplest solution is often the best one:
function replicate(arr, times) {
var al = arr.length,
rl = al*times,
res = new Array(rl);
for (var i=0; i<rl; i++)
res[i] = arr[i % al];
return res;
}
(or use nested loops such as #UsamaNorman).
However, if you want to be clever, you also can repeatedly concat the array to itself:
function replicate(arr, times) {
for (var parts = []; times > 0; times >>= 1) {
if (times & 1)
parts.push(arr);
arr = arr.concat(arr);
}
return Array.prototype.concat.apply([], parts);
}
Basic but worked for me.
var num = 2;
while(num>0){
array = array.concat(array);
num--}
Here's a fairly concise, non-recursive way of replicating an array an arbitrary number of times:
function replicateArray(array, n) {
// Create an array of size "n" with undefined values
var arrays = Array.apply(null, new Array(n));
// Replace each "undefined" with our array, resulting in an array of n copies of our array
arrays = arrays.map(function() { return array });
// Flatten our array of arrays
return [].concat.apply([], arrays);
}
console.log(replicateArray([1,2,3],4)); // output: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
What's going on?
The first two lines use apply and map to create an array of "n" copies of your array.
The last line uses apply to flatten our recently generated array of arrays.
Seriously though, what's going on?
If you haven't used apply or map, the code might be confusing.
The first piece of magic sauce here is the use of apply() which makes it possible to either pass an array to a function as though it were a parameter list.
Apply uses three pieces of information: x.apply(y,z)
x is the function being called
y is the object that the function is being called on (if null, it uses global)
z is the parameter list
Put in terms of code, it translates to: y.x(z[0], z[1], z[2],...)
For example
var arrays = Array.apply(null, new Array(n));
is the same as writing
var arrays = Array(undefined,undefined,undefined,... /*Repeat N Times*/);
The second piece of magic is the use of map() which calls a function for each element of an array and creates a list of return values.
This uses two pieces of information: x.map(y)
x is an array
y is a function to be invoked on each element of the array
For example
var returnArray = [1,2,3].map(function(x) {return x + 1;});
would create the array [2,3,4]
In our case we passed in a function which always returns a static value (the array we want to duplicate) which means the result of this map is a list of n copies of our array.
You can do:
var array = ['1','2','3'];
function nplicate(times, array){
//Times = 2, then concat 1 time to duplicate. Times = 3, then concat 2 times for duplicate. Etc.
times = times -1;
var result = array;
while(times > 0){
result = result.concat(array);
times--;
}
return result;
}
console.log(nplicate(2,array));
You concat the same array n times.
Use concat function and some logic: http://www.w3schools.com/jsref/jsref_concat_array.asp
Keep it short and sweet
function repeat(a, n, r) {
return !n ? r : repeat(a, --n, (r||[]).concat(a));
}
console.log(repeat([1,2,3], 4)); // [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
http://jsfiddle.net/fLo3uubk/
if you are inside a loop you can verify the current loop index with the array length and then multiply it's content.
let arr = [1, 2, 3];
if(currentIndex > arr.length){
//if your using a loop, make sure to keep arr at a level that it won't reset each loop
arr.push(...arr);
}
Full Example:
https://jsfiddle.net/5k28yq0L/
I think you will have to write your own function, try this:
function dupArray(var n,var arr){
var newArr=[];
for(var j=0;j<n;j++)
for(var i=0;i<arr.length;i++){
newArr.push(arr[i]);
}
return newArr;
}
A rather crude solution for checking that it duplicates...
You could check for a variation of the length using modulus:
Then if it might be, loop over the contents and compare each value until done. If at any point it doesn't match before ending, then it either didn't repeat or stopped repeating before the end.
if (array2.length % array1.length == 0){
// It might be a dupe
for (var i in array2){
if (i != array1[array2.length % indexOf(i)]) { // Not Repeating }
}
}

Categories

Resources