Determine in Javascript if an array forms an almost increasing sequence

Currently, I am tackling some challenging Javascript problems on Code Signal and came across this particular question:

When presented with an array of integers in a sequence, can you determine if it is possible to create a strictly increasing sequence by removing no more than one element from the array?**

Note: A sequence a0, a1, ..., an is deemed strictly increasing if a0 < a1 < ... < an. Also, a sequence comprising only one element is considered strictly increasing as well.

For example, if we have a sequence = [1, 3, 2, 1], the output should be almostIncreasingSequence(sequence) = false.

The given array does not contain any single element that can be omitted to achieve a strictly increasing sequence. On the other hand, for a sequence like [1, 3, 2], the expected output is almostIncreasingSequence(sequence) = true.

In this case, removing the number 3 from the array results in the strictly increasing sequence [1, 2]. Alternatively, you could remove 2 to get [1, 3].

To solve this problem, my approach involves iterating through the sequence array to check if the current element exceeds the subsequent element. If so, the current element is removed. Then, a counter is incremented, and if the count is less than 2, return true; otherwise, return false.

Below is the code snippet:

function almostIncreasingSequence(sequence) {
    // Return true if array has 1 or 2 elements
    if(sequence.length <= 2) {
        return true;
    }

    // Keep track of removed numbers
    let numberRemoved = 0;

    // Loop through array, compare current element with next
    // If greater than next, increment numberRemoved and remove current element
    for(let i = 0; i < sequence.length; i++) {        
        if(sequence[i] >= sequence[i + 1]) {
            numberRemoved++;

            // Remove element that's greater than next
            let removed = sequence.splice([i], 1);
            i = 0;

            console.log(sequence);
        }

    }

    for(let j = 0; j < sequence.length; j++) {
        if(sequence[j] >= sequence[j + 1]) {
            numberRemoved++;
        }
    }

    // Pass if number of removals is less than 2
    if(numberRemoved < 2) {
        return true;
    }
    else {
        return false;
    }  
}

This implementation solves most test cases except for two instances where handling edge cases becomes crucial. For example, when comparing sequence[i] and sequence[i + 1], removing sequence[i] at times may not give the desired result, and removing sequence[i + 1] might actually lead to success instead. How can this issue be resolved without resorting to a second loop through the array?

Answer №1

When coming across a decreasing number in the sequence, it is necessary to decide which of the two consecutive numbers should be removed. The options are as follows:

  1. The last number is too large
  2. The current number is too small

If neither of these options can rectify the decrease, then the array does not constitute an "almost increasing sequence" since it would require at least one more removal.

function almostIncreasingSequence(sequence) {
  let removed = 0;
  let i = 0;
  let prev = -Infinity;
  
  // Continue loop until no more than 2 removals have occurred and we haven't reached end of array
  while(removed < 2 && i < sequence.length) {
    if(sequence[i] > prev) { // If current number is larger than previous
      prev = sequence[i]; // Set current as new previous
    } else if (i === sequence.length - 1 || sequence[i+1] > sequence[i-1]) {
      removed++; // Increment removal counter
    } else if (i < 2 || sequence[i] > sequence[i-2]) {
      removed++;
      prev = sequence[i];
    } else {
      return false; 
    }
    i++;
  }

  return removed < 2; // True if removals are less than 2
}

console.log(almostIncreasingSequence([1, 3, 2, 1])); // false
console.log(almostIncreasingSequence([1, 3, 2])); // true
console.log(almostIncreasingSequence([3, 5, 67, 98, 3])); // true
console.log(almostIncreasingSequence([4, 3, 5, 67, 98, 3])); // false
console.log(almostIncreasingSequence([1, 4, 2, 3])); // true
console.log(almostIncreasingSequence([10, 13, 2, 9])); // false

Answer №2

The main question revolves around the concept of whether we must remove one or fewer items to achieve a sequence that is increasing. This means that you may not necessarily have to remove any item, but rather determine how many items would need to be removed for the sequence to become increasing.

Furthermore, it is crucial to continue checking without the out-of-sequence numbers causing subsequent checks to fail. In such cases, assign the lower number between the current value and the previous one to the variable prev.

function almostIncreasingSequence(sequence) {
  let removed = 0;
  let i = 0;
  let prev = -Infinity;
  
  // Condition: less than 2 removals and within array length
  while(removed < 2 && i < sequence.length) {
    if(sequence[i] > prev) { // If current element is greater than previous
      prev = sequence[i]; // Set current as previous
    } else {
      prev = Math.min(prev, sequence[i]); // Choose the lowest value
      removed++; // Increment removal count
    }
    
    i++;
  }

  return removed < 2; // Returns true if less than 2 elements were removed
}

console.log(almostIncreasingSequence([1, 3, 2, 1])); // false
console.log(almostIncreasingSequence([1, 3, 2])); // true
console.log(almostIncreasingSequence([3, 5, 67, 98, 3])); // true
console.log(almostIncreasingSequence([4, 3, 5, 67, 98, 3])); // false
console.log(almostIncreasingSequence([1, 4, 2, 3])); // true

Answer №3

To find the correct index, you can follow this method.

This technique involves checking three consecutive elements as shown below:

            v
1   2  [3   8   4]  5   6   7   -> found at index 3

Alternatively, in the next iteration, skip the previously found value by using the found index for comparison.

                v
1   2   3  [8   4   5]  6   7
            ^ omit value on found index

If there is a disruption in the sequence, check the adjacent items to avoid errors like these:

            v
1   2   3   1   2   5   6   7
        3   >   2

            v
1   2   3   8   2   5   6   7
        3   >   2

If an error is detected, it signifies that more than one element is out of place.

function inSequence(array) {
    var i,
        found;
        
    for (i = 1; i < array.length - 1; i++) {
        if ((found === i - 1 || array[i - 1] < array[i]) && array[i] < array[i + 1]) continue;
        if (array[i - 1] >= array[i + 1] || found !== undefined) return false;
        found = i;
    }
    return true;
}

console.log(inSequence([2, 1]));
console.log(inSequence([1, 2, 3]));
console.log(inSequence([2, 1, 3]));
console.log(inSequence([1, 2, 4, 3]));
console.log(inSequence([1, 2, 3, 8, 4, 5, 6, 7]));
console.log(inSequence([1, 2, 3, 8, 4, 5, 6, 9, 7]));
console.log(inSequence([2, 1, 3, 4, 5, 2]));
console.log(inSequence([1, 2, 3, 1, 2, 5, 6, 7]));
console.log(inSequence([1, 2, 3, 8, 2, 5, 6, 7]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №4

Uncertain about the question's intent, but it seems like this code could potentially provide a solution...

function checkOrder(arraySeq)
  {
  let prev = -Infinity
    , result  = true
    , invalid  = false
    ;
  for(let item of arraySeq) 
  {
    if (item<=prev)
      {
      if (invalid) { result=false; break }
      else     { invalid=true         }
      }
    prev=item
    }
  return result
  }


console.log(checkOrder([1, 3, 2, 1]));         // false
console.log(checkOrder([1, 3, 2]));            // true
console.log(checkOrder([3, 5, 67, 98, 3]));    // true
console.log(checkOrder([4, 3, 5, 67, 98, 3])); // false

Answer №5

To determine if removing an index in an array would result in an increasing sequence, we should check if the remaining indices adhere to the increasing order rule.

a i < a i+1

If one index violates this rule, then the other indices must maintain the order for the array to be considered almost increasing.

function almostIncreasingSequence(sequence) {
let unorderedIndex = 0;
for(let i = 1; i < sequence.length; i++ ){
if( sequence[i-1] >= sequence[i] ) {
    unorderedIndex++;

// an array that's almost increasing would just have one unordered index
    if( unorderedIndex > 1 ) return false;
    
    if( sequence[i-2] >= sequence[i] && sequence[i-1] >= sequence[i+1])
        return false;
    }
} 
return true;
    }

Answer №6

Let's consider a straightforward approach.

function checkIncreasingSequence(arr) {
  // set removedItems to 0.
  let removedItems = 0;

  // loop through the array
  for(let index=0; index<arr.length-1; index++) {
    // if current element is greater than the next element e.g., [3, 1, 2]; 3 > 1
    if(arr[index] > arr[index+1]) {
      // increment counter
      removedItems++;
    } 
  }
  // if more than 2 items have been removed, return false, otherwise return true 
  return removedItems <= 1;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to reset Owl Carousel following an ajax request?

I am attempting to reinitialize the owl carousel following a successful ajax call. The ajax call will update the data while retaining the same view. I am encountering an issue where the carousel structure in the view does not reinitialize, and I am unsure ...

Unable to append HTML table row to designated table

I am trying to populate an HTML table with the JSON string data I receive. The object data seems correct, but for some reason, it is not getting appended to the table. Can you help me identify what's wrong with my jQuery append statement? functio ...

What is the best way to link a JavaScript file from a node package in an HTML document?

After developing a Node.js Express App using JetBrains WebStorm, I utilized npm (via File->Settings->Node.js and NPM) to install a package called validator, specifically designed for string validation. The installation of the package went smoothly u ...

Methods for handling asynchronous completion using jQuery

While there are numerous discussions on this topic, I have not found a definitive answer to my question. The solutions proposed often seem overly complex for what should be a simple issue. So, my main question is how can I make the following code run in s ...

Using Object Values and Subvalues to Assign Element Attributes in jQuery

I have a weekly schedule that I update regularly using a static table layout: <table> <tr class="live gm fsp"> <td>Oct. 7</td> <td>12:30 pm</td> <td class="prog">Show 1</td> <td>Team ...

Persist user input even after reloading the page

In order to enhance the user experience, I would like to implement a feature where the data entered by the user is preserved even if they refresh, reload, or close the page. This includes retaining the selections made in the select elements. Additionally, ...

When attempting to access the shazam API, I encountered an issue where my useTopChartsQuery function was not recognized as a valid function

Welcome to the shazamCore.js file import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const shazamCoreApi = createApi({ reducerPath: "shazamCoreApi", baseQuery: fetchBaseQuery({ baseUrl: "https ...

Creating JSX elements in React by mapping over an object's properties

I need to display the properties of an object named tour in JSX elements using React without repeating code. Each property should be shown within a div, with the property name as a label and its value next to it. Although I attempted to iterate over the o ...

Are there any methods available to adjust the size of a View component in react-native?

My react-native application includes a View that contains several components. The layout displays perfectly on iPhone 6 and 5 models, but on an iPhone 4s, the bottom of one component is being clipped slightly. I'm aware of scaling base64 icons, but I ...

In Python lists/arrays, prevent negative indexing from wrapping around when using slices

Although I often find the concept of negative number wraparound (e.g. A[-2] indexing the second-to-last element) quite useful in many scenarios, when it occurs within a slice, it can become more of a nuisance than a helpful feature. At times, I wish there ...

In order to properly execute the JavaScript code, it is essential to create a highly customized HTML layout from the ER

I am currently utilizing this resource to create a gallery of images on my Rails page. Here is the HTML code required to display the images: <a href="assets/gallery/ave.jpg" title="Ave" data-gallery> <img src="assets/gallery/ave_tb.jpg" alt="Av ...

Choose particular elements within an array

I am working with an array that contains certain lines I need to highlight, specifically A and B: [0] A1 [1] a line I don't need [2] B1 [3] another line I'm not interested in [4] A2 [5] yet another line I want to ignore [6] B2 [7] something else ...

The $resource.query function will now return an array of characters instead of a single string when splitting strings

Recently, I've been working on utilizing an Angular $resource in my project. Here's a snippet of the code: angular.module('app') .factory('data', function ($resource) { var Con = $resource('/api/data', {}, { ...

abandoning the upload of an item into a THREE.js environment

Currently, I am working on a THREE.js scene where I need to prevent uploading multiple files into the scene simultaneously. The setup involves using Angular to implement the three js scene and canvas as a factory to maintain only one instance of a canvas a ...

What is the best way to save request URLs in JavaScript while following the DRY principle?

Is there a standard practice in JavaScript for storing the URLs of endpoints used in AJAX applications? Would you, for instance, consider creating a "Service" class to encapsulate the URLs? ...

Custom action in Bokeh with a personalized icon

Currently, I am working on creating custom actions for a bokeh plot within the toolbar. In order to achieve this, I require custom icons as well. To begin, I referred to this example which demonstrates creating a drawing tool. So far, everything is functi ...

Guide on implementing tail.select in a VueJS project

As a newcomer to VueJS, I am facing issues with using the tail.select plugin in my VueJS project. Even though I have imported the plugin in my main.js file using import 'tail.select' When I try to call tail.select(".select") in the mounted hook ...

Receiving SMS with Node.js/Express from ESP32 using SIM800L: A Step-by-Step Guide

As part of my project, I am tasked with receiving SMS messages from an ESP32 device that is equipped with a SIM800L module. This SIM800L module uses a personal SIM card with its own phone number. Currently, I am utilizing Node.js along with Express.js for ...

Changing an array of character pointers to lowercase in the C programming language

I am facing an issue with converting all the strings in my char pointer array to lowercase. Here is what I have attempted so far: char* wordArray[ARRAY_MAX]; In order to convert each string to lowercase, I initially looped through the array and used a p ...

Searching in the Kendo Dropdown List using text and value

$(document).ready(function() { $("#selection").kendoDropDownList({ filter: "startswith", dataTextField: "SelectionName", dataValueField: "SelectionID", dataSour ...