Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all the same numbers in the array

I have an array with numbers in the range of 0 - 100. I need to find all the same numbers and add 1 to them.

my code worked well with arrays like [100, 2, 1, 1, 0]

const findAndChangeDuplicates = (arr: any) => {
    for (let i = arr.length - 1; i >= 0; i--) {
        if (arr[i + 1] === arr[i] && arr[i] <= 5) {
            arr[i] += 1;
        } else if (arr[i - 1] === arr[i] && arr[i] >= 5) {
            arr[i] -= 1;

            findAndChangeDuplicates(arr);
        }
    }

    return arr;
};

but when I came across this [100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0]

my code let me down.

Expected Result: [100, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Have any ideas?

like image 401
Grigri Avatar asked Jul 31 '19 13:07

Grigri


People also ask

How do you find a repeated number in an array?

Duplicate elements can be found using two loops. The outer loop will iterate through the array from 0 to length of the array. The outer loop will select an element. The inner loop will be used to compare the selected element with the rest of the elements of the array.

How do I find duplicate numbers?

Find the Duplicate Number - LeetCode. Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive. There is only one repeated number in nums , return this repeated number. You must solve the problem without modifying the array nums and uses only constant extra space.


2 Answers

An approach by using at least one loop from the end to adjust the values and if necessary another loop from the beginning to set the largest value to 100.

Both loops feature a value variable v. In the first loop, it starts with the last value of the array and increments its value and check is the item is smaller than this value.

If smaller, then the value is assigned, otherwise the actual value is taken for the next item.

if necessary, the other loop works in opposite direction and with a start value of 100 and checks if the item is greater than wanted and takes the smaller value, or the value is taken from the item.

The result is an array which has a gereatest value of 100 at start and goes until zero or greater to the end of the array.

function update(array) {
    var i = array.length,
        v = array[--i];

    while (i--) if (array[i] < ++v) array[i] = v; else v = array[i];
    if (array[0] > 100) {
        v = 100;
        for (i = 0; i < array.length; i++) {
            if (array[i] > v) array[i] = v; else v = array[i];
            v--;
        }
    }
    return array;
}

console.log(update([100, 2, 1, 1, 0]));
console.log(update( [100, 100, 99, 86, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0]))
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 71
Nina Scholz Avatar answered Sep 17 '22 13:09

Nina Scholz


The following assumes you want them ordered from highest to lowest, if not this might ba as well as useless to you.

The idea is to first create an Object to keep track of how many of each number exist. We then map each value by first checking whether it's unique and if not increasing it until we can't find any value inside the Object anymore. This will not neatly order the numbers by itself so we will have to sort afterwards.

let arr1 = [100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0],
    arr2 = [100, 2, 1, 1, 0];

const f = (arr) => arr.reduce((a,c) => (a[c] = (a[c] || 0) + 1, a),{}),
      g = (arr, obj) => arr.map(v => {
        if (obj[v] > 1) {
          let i = 1;
          obj[v] = obj[v] - 1;
          while (obj[v + i]) {
            i++;
          }
          obj[v + i] = (obj[v + i] || 0) + 1;
          return v + i;
        } else {
          return v;
        }
      }).sort((a,b) => +b - +a);

console.log(g(arr1, f(arr1)))
console.log(g(arr2, f(arr2)))
like image 29
claasic Avatar answered Sep 18 '22 13:09

claasic