Determining the largest range possible in a sorted array of integers

I need help with a JavaScript implementation for the following challenge.
Imagine we have a sorted array:

[1,2,5,9,10,12,20,21,22,23,24,26,27]

I want to find the length of the longest consecutive range that increments by 1 without duplicates.

In the provided example, we have the following ranges:

1,2
9,10
20,21,22,23,24 // longest range here
26,27

Therefore, the expected result for this example should be 5.

While I know how to solve this problem using a straightforward method, I am curious if there is a more efficient and concise algorithm available.

Answer №1

An Alternative Approach

While my solution may not be more efficient than others, it offers a concise code that iterates over the array only once, except for the initial element. Below is my proposed solution:

var arr = [1, 2, 5, 9, 10, 12, 20, 21, 22, 23, 24, 26, 27];
var streak = 0, best = 0, bestStart;
for (var i = 1; i < arr.length; i++) {
  if(arr[i]-arr[i-1] === 1) streak++;
  else streak = 0;
  if (streak > best) [best, bestStart] = [streak, i - streak];
}
var bestArr = arr.slice(bestStart, bestStart + best + 1);
console.log('Best streak: '+bestArr);

Optimizing Performance

Upon reviewing the code, I identified a way to enhance its performance slightly by avoiding checking the last few elements of the array based on the previous value of best:

var arr = [1, 2, 5, 9, 10, 12, 20, 21, 22, 23, 24, 26, 27];
var streak = 0, best = 0, bestStart;
for (var i = 1; i < arr.length; i++) {
  if(best > arr.length - i + streak) break;
  if(arr[i]-arr[i-1] === 1) streak++;
  else streak = 0;
  if (streak > best) [best, bestStart] = [streak, i - streak];
}
var bestArr = arr.slice(bestStart, bestStart + best + 1);
console.log('Best streak: '+bestArr);

Answer №2

To find a solution, we can iterate through the array and maintain the current range as long as the numbers are consecutive. When we encounter a number that is not a successor of the previous number, we close the current range and compare its length to the length of the last range.

This iterative approach allows us to update the maximum range length in constant time, resulting in an O(n) algorithm where n is the number of elements in the input array.

A pseudocode implementation similar to C# could look like this:

int MaximumLength = minus infinity;
int CurrentValue = Input[0];
int CurrentLength = 1;

for(int i = 1; i < Input.Length; i++)
{
    if (CurrentValue + 1 == Input[i])
    {
        // same range
        CurrentLength++;
    }
    else
    {
        // new range
        MaximumLength = Math.Max(MaximumLength, CurrentLength);
        CurrentLength = 1;
    }
    CurrentValue = Input[i];
}
// check current length after loop termination
MaximumLength = Math.Max(MaximumLength, CurrentLength);

The time complexity of this algorithm cannot be improved beyond O(n) because reading the input alone requires at least O(n) time. This implies that every element in the input affects the result, making it necessary to examine each one. Even Philipp Maurer's suggested algorithm would also have an O(n) runtime when the maximum range length is only 1, meaning there are no consecutive numbers in the input array.

Answer №3

To improve efficiency, it's recommended to calculate the maximum length first rather than last in this context.

Initialize max as 0
Set n as the length of the array
While n is greater than 2
  Initialize m as 0
  While m is less than or equal to (the length of the array - n)
    Set first as m
    Set last as m + n - 1 
    Calculate the difference as (value of element 'last' in array) - (value of element 'first' in array)
    if diff equals n - 1 then
      Update max to be n
      Stop the loop
    end if
    Increment m
  end while
  Decrement n
end while

Edit (javascript implementation)

var a = [1,2,5,9,10,12,20,21,22,23,24,26,27];
var max = 1;
var n = a.length;
while(n is greater than 2) {
  var m = 0;
  while(m is less than or equal to a.length - n)
  {
    var first = m;
    var last = m + n - 1;
    var diff = a[last] - a[first];
    if (diff is equal to n - 1 && diff is greater than max) {
      Update max to be n;
      Break out of inner loop;
    }
    increment m;
    }
  decrement n;
}

console.log(max);

JSFiddle

Answer №4

One efficient approach could be to loop through the input array and compare each element with the previous one to find the longest range. Here is a sample implementation:

function findLongestRange(input) {
  let maxLength = 0
  let currentLength = 0

  for (let i = 0; i < input.length; i++) {
    if (i !== input.length) {
      if (input[i] === input[i + 1] - 1) {
        currentLength++
      } else {
        if (maxLength <= currentLength && currentLength !== 0) {
          maxLength = currentLength + 1
        }
        currentLength = 0
      }
    }
  }

  return maxLength
}

const data = [1, 2, 5, 9, 10, 12, 20, 21, 22, 23, 24, 26, 27]
console.log(findLongestRange(data))

To verify how this function performs with different inputs, here's a version of it with test cases included:

const data = [1, 2, 5, 9, 10, 12, 20, 21, 22, 23, 24, 26, 27]

function findLongestRange(input) {
  let maxLength = 0
  let currentLength = 0

  for (let i = 0; i < input.length; i++) {
    if (i !== input.length) {
      if (input[i] === input[i + 1] - 1) {
        currentLength++
      } else {
        if (maxLength <= currentLength && currentLength !== 0) {
          maxLength = currentLength + 1
        }
        currentLength = 0
      }
    }
  }

  return maxLength
}

console.clear()
;[
  [[1,2,5,6,7,1,2], 3],
  [[], 0],
  [data, 5],
  [[1,2,3], 3],
  [[1,3,4,6,8,1], 2],
  [[1,3,5], 0],
].forEach((test, index) => {
  const result = findLongestRange(test[0])
  console.assert(result === test[1], `Fail #${index}: Exp: ${test[1]}, got ${result}`)
})

Answer №5

An example of Python code:

l = [1,2,5,9,10,12,20,21,22,23,24,26,27]
current_range = None
current_range_val = 0
max_range = 0
max_range_val = 0
for i, j in zip(l, l[1:]):
    if j - i == 1:
        current_range_val += 1
        if current_range is None:
            current_range = (i, j)
        current_range = (current_range[0], j)
    else:
        if current_range_val > max_range_val:
            max_range = current_range
            max_range_val = current_range_val
        current_range_val = 0
        current_range = (j, None)

print(max_range)

This code snippet will output the range as:

(20, 24)

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

Vue event emissions are not triggered or detected

This is the functionality of the Child Component: registerUser() { if (this.$refs.form.validate()) { this.$emit('showLoader', true); // Triggers this.$fireAuth .createUserWithEmailAndPassword(this.email, this.password) .the ...

What exactly is the purpose of the QueryString function and how does it work

I recently took on the role of editor for a website that I did not create. One of the webpages contains a map feature, and I've been tasked with changing how the map loads initially on the webpage. As I review the JavaScript code, I'm unsure if ...

What is the best way to enforce a required bindings property in an AngularJS component?

Suppose I have the following component defined: angular.module('myApp').component('myComponent', { templateUrl: 'myComponent.html', bindings: { myPropOne: '<', myPropTwo: '<' ...

Redux Persist causes the redux state to become undefined

I recently added redux-persist to my project and now I am facing an issue where all of my Redux states are returning undefined. Previously, all the Redux states were functioning properly. However, after incorporating redux-persist, they are no longer work ...

Partial data sent through Ajax to PHP file

Encountering a peculiar issue with Ajax where the entire string data is not being sent to the php script. Here is the string: "<p class="MsoNormal" style="text-align:justify"><b><u><span lang="DE" style="font-size:10.0pt;mso-bidi-fon ...

What is the best way to link HTML transformations across several classes?

Is it possible to combine multiple transforms in a single element to create a unique end result? It seems that when applying multiple transform properties to an element, only one of them will be recognized. For example, trying to transform a div with bot ...

stop the page from refreshing when clicking on the map area

http://jsbin.com/iTeNiJIt/1/edit?output I currently have multiple map areas on my webpage. When a user clicks on any of these areas, I want to create an animation without refreshing the page. However, I am facing an issue where the page refreshes every ti ...

One method for assigning a unique identifier to dynamically generated buttons with jQuery

<table border="0" class="tableDemo bordered"> <tr class="ajaxTitle"> <th width="2%">Sr</th> <th >SM</th> <th >Campaign</th> <th >Day1</th> <th >Da ...

What is the best way to transmit a collection of JSON documents from the server?

Need help with vue.js code. It's not working as intended, any suggestions? Below is the code snippet: mounted(){ fetch('/', { method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, *cors, ...

Menu icon in Next.js/React/Tailwind not triggering close action when clicked again, causing responsiveness issue

Hey there, I'm relatively new to working with Next.js and React. Right now, I'm tackling the challenge of creating a responsive navbar that toggles open and closed when clicking on the hamburger icon (and should also close when clicked outside th ...

Receive the most recent query in a Nuxt plugin following the completion of page loading

So, here's the issue - I have a plugin containing some functions that are supposed to update URL queries. However, every time I run $global.changePage(2) or $global.changeLimit(2), the console.log(query) outputs an empty object and doesn't show t ...

Guide on accessing JSON field through GSON library with @SerializedName annotation

I am encountering an issue with parsing the JSON object provided below: "paymentCurrency": "eur", "paymentOptions": [ { "paymentOptionId": "1CeGuJt2nkxmaMVf", ...

Ways to minimize an array of objects by shared key values?

Suppose I have an array of objects structured like this: var jsonData = [ {"DS01":123,"DS02":88888,"DS03":1,"DS04":2,"DS05":3,"DS06":666}, {"DS01":123,"DS02":88888,"DS03":2,"DS04":3,"DS05":4,"DS06":666}, {"DS01":124,"DS02":99999,"DS03":3,"DS04" ...

Encountering an issue with importing createSagaMiddleware from 'redux-saga' while working on my create-react-app project

Within my create-react-app, I have the following import: import createSagaMiddleware from 'redux-saga'; However, there seems to be an issue with importing createSagaMiddleware in my system. The versions I am currently using are: node 12.13.0 n ...

Utilizing JavaScript to transition a grayscale thumbnail image to vibrant color

I am a beginner in the world of web development and I have no idea how to begin coding a JavaScript function that will smoothly transition a grayscale thumbnail image into a color thumbnail image when the user hovers their mouse over it, and then back to g ...

Place the new item right under the chosen items within the nested list

My nested list with a collapse feature is almost complete. However, I am encountering an issue where I need to add content just below the selected item when I click on the "add" button. For example, in the attached demo, there is a nested list. If I select ...

Manipulate text with jQuery

Is there a way to remove 'http://' or 'https://' from text using javascript? I am looking for regex solutions as well. This is what I have tried so far: JSFIDDLE HTML: <div class="string"></div> JS: $text = $('.s ...

Is there a standardized method for obtaining a date in the format of six digits as YYMMDD?

In my current project, I'm developing a function that generates a list of dates represented in a 6-digit format beginning from the present day up until August of 2018. The desired output should resemble the following: [190322, 190321, 190320, ...] I ...

Event triggered when a Socket.IO connection is disconnected

Everything seems to be working well with my code when a new user joins, but I'm encountering issues when a user leaves as it doesn't display anything. Can someone point out the error in my code? Below is my server-side code: const express = requ ...

Change the input field to uppercase using JavaScript but do not use inline JavaScript

Hey there! I have a basic script set up (see below) with an input field allowing users to enter a query. This query is then sent to a socrata webservice to request specific data, which is displayed in an alert box. So far, everything works smoothly. var l ...