How can I find all first indexes of sequence of consecutive zeroes in an array? - javascript

I am trying to push all first indexes that point to a start of a sequence of consecutive 0s from the array A into a new array arr.
var C determines the amount of 0s in the sequence. For example, if C is 2, the algorithm will look for 00s, if C is 3 it will look for 000s and so on. N is the length of an array A. The algorithm seems to work, but for some reason the values in the new array arr are duplicated
var A = [1, 0, 0, 1];
var N = 4;
var C = 1;
function S(A, N, C) {
var arr = [];
for (var i = 0; i < N; i++) {
for (var j = 0; j <= C; j++) {
if ((A[i] == 0) && (A[i + j] == 0)) {
arr.push(i);
}
}
}
console.log(arr);
return -1;
}
/// console result:
Array(5)
0: 1
1: 1
2: 2
3: 2
//Expected:
0: 1
1: 2

First I would like to recommend that you use more descriptive variable names. The fact that you need to describe what each of them means, means that they are not descriptive enough.
Also your variable N seems redundant, because arrays already have a .length property that you can use to see how many elements are in there.
The source of your error seems to be that you use a nested loop. There is no need to use nested loops. You only need to go through all elements once and keep track of the repeated zeroes. Every time you encounter a non-zero value, you reset the sequence count to 0. If do encounter a zero you increment the sequence count and afterwards you check if the sequence count is equal to the number of zeroes you passed as an argument. In that case you want to push the first index to the resulting array and reset the sequence count to 0 again.
function getFirstIndexesOfSequenceOfConsecutiveZeroes(input, numberOfRepeatedZeroes) {
if (numberOfRepeatedZeroes <= 0) {
throw new Error("numberOfRepeatedZeroes need to be 1 or higher");
}
var firstIndexes = [];
let sequenceStartIndex;
let sequenceCount = 0;
for (var i = 0; i < input.length; i++) {
if (input[i] !== 0) {
sequenceCount = 0;
} else {
if (sequenceCount == 0) {
sequenceStartIndex = i;
}
sequenceCount++;
}
if (sequenceCount === numberOfRepeatedZeroes) {
firstIndexes.push(sequenceStartIndex);
sequenceCount = 0;
}
}
return firstIndexes;
}
let input = [1, 0, 0, 1];
let numberOfRepeatedZeroes = 1;
console.log(getFirstIndexesOfSequenceOfConsecutiveZeroes(input, numberOfRepeatedZeroes));

Try:
function S(A, B, C) {
var arr = [];
for (var i = 0; i < B; i++) {
for (var j = 0; j <= C; j++) {
if ((A[i] == 0) && (A[i + j] == 0) && !arr.includes(i)) {
arr.push(i);
}
}
}
console.log(arr);
return -1;
}
With this simple add in the if, you check if the value is already in your array.

Related

find all numbers disappeared in array

Please help me to solve this leetcode problem using javascript as I am a beginner and dont know why this code is not working
Ques: Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
var findDisappearedNumbers = function (nums) {
var numLength = nums.length;
nums.sort(function (a, b) { return a - b });
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
}
}
for (var k = 0; k < nums.length; k++) {
for (var j = 1; j <= numLength; j++) {
if (nums[k] !== j) {
return j;
}
}
}
};
if there is any error in my code please let me know;
i have done the following thing
first i have sorted the array in ascending order
then i have cut all the duplicate elements
then i have created loop that will check if nums[k] !== j ;
and it will return j which is the missing number;
for example this is the testcase [4,3,2,7,8,2,3,1]
first my code will sort this in ascending order [1,2,2,3,3,4,7,8]
then it will remove all duplicate elements and it will return [1,2,3,4,,7,8]
and then it will check nums[k] is not equal to j and it will print j
I think it'd be easier to create a Set of numbers from 1 to n, then just iterate through the array and delete every found item from the set:
var findDisappearedNumbers = function(nums) {
const set = new Set();
for (let i = 0; i < nums.length; i++) {
set.add(i + 1);
}
for (const num of nums) {
set.delete(num);
}
return [...set];
};
console.log(findDisappearedNumbers([4,3,2,7,8,2,3,1]));
To fix your existing code, I'm not sure what the logic you're trying to implement in the lower section, but you can iterate from 1 to numLength (in the outer loop, not the inner loop) and check to see if the given number is anywhere in the array. Also, since you're mutating the array with splice while iterating over it in the upper loop, make sure to subtract one from i at the same time so you don't skip an element.
var findDisappearedNumbers = function(nums) {
var numLength = nums.length;
nums.sort(function(a, b) {
return a - b
});
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
i--;
}
}
const notFound = [];
outer:
for (var j = 1; j < numLength; j++) {
for (var k = 0; k < nums.length; k++) {
if (nums[k] === j) {
continue outer;
}
}
notFound.push(j);
}
return notFound;
};
console.log(findDisappearedNumbers([4, 3, 2, 7, 8, 2, 3, 1]));
#CertainPerformance certainly cracked it again using the modern Set class. Here is a slighly more conservative approach using an old fashioned object:
console.log(missingIn([4,3,2,7,8,2,3,1]));
function missingIn(arr){
const o={};
arr.forEach((n,i)=>o[i+1]=1 );
arr.forEach((n) =>delete o[n] );
return Object.keys(o).map(v=>+v);
}
My solution for the problem to find the missing element
var findDisappearedNumbers = function(nums) {
const map={};
const result=[];
for(let a=0;a<nums.length;a++){
map[nums[a]]=a;
}
for(let b=0;b<nums.length;b++){
if(map[b+1]===undefined){
result.push(b+1)
}
}
return result;
};
Example 1:
Input: nums = [4,3,2,7,8,2,3,1]
Output: [5,6]
Example 2:
Input: nums = [1,1]
Output: [2]

How to return the length of a contiguous subarray with specific criteria

I'm tasked with creating an array that takes another array and returns the number of contiguous subarrays for each index that fulfills the following conditions:
-The value at index i is the maximum value of the subarray
-The contiguous subarray must begin or end with i
I'm almost there but I'm missing the code to ensure that the function checks the array elements that aren't sat directly either side of i (see my code below). I think I might need some sort of recursive call that runs the if statement again while passing through the updated values of 'forward' and 'backward'. Or maybe I'm taking the wrong approach altogether.
Any ideas?
function countSubarrays(arr){
var arr = [3, 4, 1, 6, 2];
var output = [];
for (var i = 0; i < arr.length; i++){
var total = 1;
var forward = 1;
var backward = 1;
if (arr[i] >= arr[i+forward]) {
total++;
forward++;
// Some sort of recursive call here?
}
if (arr[i] >= arr[i-backward]){
total++;
backward++;
// Some sort of recursive call here?
}
output.push(total);
}
console.log(output);
}
countSubarrays();
You need to go backwards or ahead and count the items who are smaller or equal to the actual element.
function countSubarrays(array) {
var output = [];
for (let i = 0; i < array.length; i++) {
let value = array[i],
total = 1;
j = i;
while (j-- && value >= array[j]) total++;
j = i;
while (++j < array.length && value >= array[j]) total++;
output.push(total);
}
return output;
}
console.log(countSubarrays([3, 4, 1, 6, 2]));

Missing Number Algorithm Timeout Error (JavaScript)

I'm working on a Codewars Kata that is passing all tests, except it keeps timing out. Can anyone offer advice on how to optimize this? Thanks in advance!
Here is the question breakdown -
In this kata, we have an unsorted sequence of consecutive numbers from a to b, such that a < b always (remember a, is the minimum, and b the maximum value).
They were introduced an unknown amount of duplicates in this sequence and we know that there is an only missing value such that all the duplicate values and the missing value are between a and b, but never coincide with them.
Find the missing number with the duplicate numbers (duplicates should be output in a sorted array).
Let's see an example:
arr = [10,9,8,9,6,1,2,4,3,2,5,5,3]
find_dups_miss([10,9,8,9,6,1,2,4,3,2,5,5,3]) == [7,[2,3,5,9]]
And here is my solution -
function findDupsMiss(arr) {
let missingNum = [];
let newArr = [];
arr = arr.sort((a, b) => a - b);
let dup = [...new Set(arr)];
for (let y = 1; y < dup.length; y++) {
if (dup[y] - dup[y - 1] != 1) missingNum.push(dup[y] - 1)
}
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) newArr.push(arr[i])
}
}
missingNum.push(newArr);
return missingNum;
}
You could take the power of an object and the standard sorting of keys who could be used as indices of an array (positive 32 bit numbers).
This attempt has two parts
count all numbers
iterate all keys of the object with their appearances and
check if it has the missing number between the actual item and the previous item. If so, assign the missing values,
check the count and push the key if the count is greater than one.
This code completes in 7410 ms.
function findDupsMiss(arr) {
var hash = Object.create(null),
i = arr.length,
l,
v,
keys,
missing,
dupes = [],
previous, item;
while (i--) {
v = arr[i];
if (!hash[v]) {
hash[v] = 0;
}
hash[v]++;
}
keys = Object.keys(hash);
l = keys.length;
for (i = 0; i < l; i++) {
item = +keys[i];
if (previous + 1 !== item) {
missing = previous + 1;
}
if (hash[item] > 1) {
dupes.push(item);
}
previous = item;
}
return [missing, dupes];
}

leetcode 3sum assistance, how can i optimize this answer?

I have a solution that seems to pass most of the tests but is too slow. If i'm not mistaken, the complexity is O(n^3) due to the three for loops.
My idea was to start at the first three positions of the array at i, j and k, sum them, and see if it adds up to 0.
The functions objective is:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
var threeSum = function(nums) {
var originalArray = nums
var lengthArray = nums.length
//sort array smallest to largest
nums.sort(function(a,b) {
return a-b
})
function arrayEqual(array1, array2){
var equal = false
array1.forEach((value1) => {
if(array1 === array2){
equal = true
}
})
return equal
}
var sum = 0;
var answerArray = [];
//start from first digit and add from there
for(var i = 0; i<lengthArray; i++){
for(var j = i+1; j<lengthArray; j++){
for(var k = j+1; k<lengthArray; k++){
if((nums[i]+nums[j]+nums[k] === 0)){
if(!arrayEqual(answerArray, [nums[i],nums[j],nums[k]])){
answerArray.push([nums[i],nums[j],nums[k]])
}
}
}
}
}
return Array.from(new Set(answerArray.map(JSON.stringify)), JSON.parse)
};
How can i get around having to use three for loops to make this work (aka how do i optimize this solution?)
Think this problem in this way. Choose any number from the array say k. Now you need to find two other numbers in the array which add to -k. The resulting sum of three numbers will be k + (-k) = 0.
So this problem is reduced to find two numbers in the array which adds to a given number which is O(n) using two pointers method if given array is sorted.
In a nutshell, sort the array, take each number (k) one by one (O(n)), find two other numbers with sum -k (O(n)).
Total time complexity : O(n) * O(n) = O(n2)
You can solve the problem in a runtime of O(n^2). Here is the solution using JavaScript
var threeSum = function(nums) {
var solutions = [];
var target = 0;
nums.sort(function(a, b) {
return a - b;
});
for(var i = 0; i < nums.length - 2; i++) {
if(i === 0 || (i > 0 && nums[i] !== nums[i - 1])) {
var lo = i + 1;
var hi = nums.length - 1;
var sum = - nums[i];
while(lo < hi) {
if(nums[lo] + nums[hi] === sum) {
solutions.push([nums[i],nums[lo],nums[hi]]);
while (lo < hi && nums[lo] === nums[lo + 1]) lo++;
while (lo < hi && nums[hi] == nums[hi-1]) hi--;
lo++; hi--;
}else if (nums[lo] + nums[hi] > sum) {
hi--;
}else {
lo++;
}
}
}
};
return solutions;
}

Returning a missing element from a string of integers

I'm trying to write a function that accepts an array of unique integers between 0 and 9 (inclusive), and returns the missing element. Here's what I've got. So near but so far.
var currentPlace = 0;
function getMissingElement(superImportantArray){
while (currentPlace < 9){
for (var i = 0; i < 10; i++) {
var arrayNum = superImportantArray[currentPlace]
if (i == arrayNum) {
currentPlace ++;
console.log("so it's not " + i);
}
else if (i !=arrayNum) {
console.log("try..." + i);
}
}
}
}
// run
var myArray = [0,5,1,3,2,9,7,6,4]; // this test should return 8
getMissingElement(myArray);
I'm not sure i'm approaching this correctly. Thanks for your time.
Just wanted to post my answer from the comments. A simpler way to handle this, in my opinion, is to loop over the original array, and flag a new array at the index that they represent. For example, if the number is 4, flag the 4th index in the new array. The reason for all this is because once this is done, one index should be left unflagged. All that would be left to do is find the unflagged index.
Here's an example (I commented the code here, not the fiddle):
function findMissing(array, min, max) {
var missing, unfilledArray, i, j;
// Array to hold the flags
unfilledArray = [];
for (i = min, j = max; i <= j; i++) {
// Flag the index in the new array with the current value
unfilledArray[array[i]] = true;
}
for (i = min, j = max; i <= j; i++) {
// Loop over new array and find the unflagged index
currentUnfilled = unfilledArray[i];
if (!currentUnfilled) {
// Current index not flagged
missing = i;
break;
}
}
return missing;
}
DEMO: http://jsfiddle.net/6GAyw/
The other little feature I added was that you explicitly specify the minimum and maximum value, which, in your case, is 0 and 9. This feature allows this solution to be used on any range of numbers (unlike my original comment/suggestion).
And not that I fully understand big O notation, but I believe this is O(2n), not O(n^2), since there aren't nested loops/indexOf.
If you were looking to get all missing numbers in a range, you can easily modify the function to return an array of unflagged indexes instead. Here's an example:
function findMissing(array, min, max) {
var missing, unfilledArray, i, j;
// Array to hold the missing numbers
missing = [];
// Array to hold the flags
unfilledArray = [];
for (i = min, j = max; i <= j; i++) {
// Flag the index in the new array with the current value
unfilledArray[array[i]] = true;
}
for (i = min, j = max; i <= j; i++) {
// Loop over new array and find the unflagged index
currentUnfilled = unfilledArray[i];
if (!currentUnfilled) {
// Current index not flagged
missing.push(i);
}
}
return missing;
}
DEMO: http://jsfiddle.net/zFS89/
function getMissingElement(superImportantArray){
var result = [], length = Math.max(10, superImportantArray.length);
for (var i = 0; i < length; i++) {
if(superImportantArray.indexOf(i) == -1){
result.push(i);
}
}
return result;
}
Try this. This will return an array of missing elements else return an empty array.
DEMO FIDDLE
So here is one way to do it: Since you know that the array only contains values from 0 to 9, you can build a "set" of numbers and remove each "seen" value in the array from the set:
function getMissingElement(superImportantArray){
var numbers = {};
for (var i = 0; i < 10; i++) {
numbers[i] = true
}
for (var i = 0, l = superImportantArray.length; i < l; i++) {
delete numbers[superImportantArray[i]];
}
return Object.keys(numbers);
}
This would return an array of all numbers that are missing. If there can always only be one missing number you can easily modify this to directly return the number instead.
This should do it.
function getMissingElement(arrayTest) {
// create an array with all digits
var digitsArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var index;
for (var i=0; i<arrayTest.length; i++) {
// get the index of current digit on our array
index = digitsArray.indexOf(arrayTest[i]);
// if found, remove it from our array.
if (index >= 0) {
digitsArray.splice(index,1);
}
}
// the last remaining digit in the original array should be the one missing.
return (digitsArray[0]);
}
This one is better for the eyes.
function getMissingElement(superImportantArray) {
return superImportantArray.reduce(function (sum, value) {return sum - value;}, 45);
}

Categories