Как найти наиболее близкое число в массиве

Here’s the pseudo-code which should be convertible into any procedural language:

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)

def closest (num, arr):
    curr = arr[0]
    foreach val in arr:
        if abs (num - val) < abs (num - curr):
            curr = val
    return curr

It simply works out the absolute differences between the given number and each array element and gives you back one of the ones with the minimal difference.

For the example values:

number = 112  112  112  112  112  112  112  112  112  112
array  =   2   42   82  122  162  202  242  282  322  362
diff   = 110   70   30   10   50   90  130  170  210  250
                         |
                         +-- one with minimal absolute difference.

As a proof of concept, here’s the Python code I used to show this in action:

def closest (num, arr):
    curr = arr[0]
    for index in range (len (arr)):
        if abs (num - arr[index]) < abs (num - curr):
            curr = arr[index]
    return curr

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)

And, if you really need it in Javascript, see below for a complete HTML file which demonstrates the function in action:

<html>
    <head></head>
    <body>
        <script language="javascript">
            function closest (num, arr) {
                var curr = arr[0];
                var diff = Math.abs (num - curr);
                for (var val = 0; val < arr.length; val++) {
                    var newdiff = Math.abs (num - arr[val]);
                    if (newdiff < diff) {
                        diff = newdiff;
                        curr = arr[val];
                    }
                }
                return curr;
            }
            array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
            number = 112;
            alert (closest (number, array));
        </script>
    </body>
</html>

Now keep in mind there may be scope for improved efficiency if, for example, your data items are sorted (that could be inferred from the sample data but you don’t explicitly state it). You could, for example, use a binary search to find the closest item.

You should also keep in mind that, unless you need to do it many times per second, the efficiency improvements will be mostly unnoticable unless your data sets get much larger.

If you do want to try it that way (and can guarantee the array is sorted in ascending order), this is a good starting point:

<html>
    <head></head>
    <body>
        <script language="javascript">
            function closest (num, arr) {
                var mid;
                var lo = 0;
                var hi = arr.length - 1;
                while (hi - lo > 1) {
                    mid = Math.floor ((lo + hi) / 2);
                    if (arr[mid] < num) {
                        lo = mid;
                    } else {
                        hi = mid;
                    }
                }
                if (num - arr[lo] <= arr[hi] - num) {
                    return arr[lo];
                }
                return arr[hi];
            }
            array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
            number = 112;
            alert (closest (number, array));
        </script>
    </body>
</html>

It basically uses bracketing and checking of the middle value to reduce the solution space by half for each iteration, a classic O(log N) algorithm whereas the sequential search above was O(N):

0  1  2   3   4   5   6   7   8   9  <- indexes
2 42 82 122 162 202 242 282 322 362  <- values
L             M                   H  L=0, H=9, M=4, 162 higher, H<-M
L     M       H                      L=0, H=4, M=2, 82 lower/equal, L<-M
      L   M   H                      L=2, H=4, M=3, 122 higher, H<-M
      L   H                          L=2, H=3, difference of 1 so exit
          ^
          |
          H (122-112=10) is closer than L (112-82=30) so choose H

As stated, that shouldn’t make much of a difference for small datasets or for things that don’t need to be blindingly fast, but it’s an option you may want to consider.

Для неотсортированного массива. Для отсортированного лучше использовать бинпоиск.

Python 3.4+: tio.run

def f(a, val):
  return min((x for x in a if x > val), default=None)

a = [1, 2, 5, 22, 33, 44, 312]
print(f(a, 3))
print(f(a, 10))
print(f(a, 1000))

Более ранние версии: tio.run

def f(a, val):
  return min([x for x in a if x > val] or [None])

a = [1, 2, 5, 22, 33, 44, 312]
print(f(a, 3))
print(f(a, 10))
print(f(a, 1000))

Вывод в обоих случаях:

5
22
None

Дан отсортированный массив целых чисел, найти k ближайшие элементы к target в массиве, где k а также target заданы положительные целые числа.

The target может присутствовать или отсутствовать во входном массиве. Если target меньше или равно первому элементу входного массива, вернуть первым k элементы. Точно так же, если target больше или равно последнему элементу входного массива, вернуть последний k элементы. Возвращаемые элементы должны быть в том же порядке, что и во входном массиве.

 
Например,

Input:  [10, 12, 15, 17, 18, 20, 25], k = 4, target = 16
Output: [12, 15, 17, 18]

 
Input:  [2, 3, 4, 5, 6, 7], k = 3, target = 1
Output: [2, 3, 4]

 
Input:  [2, 3, 4, 5, 6, 7], k = 2, target = 8
Output: [6, 7]

Потренируйтесь в этой проблеме

Идея состоит в том, чтобы выполнить линейный поиск, чтобы найти точку вставки. i. Точка вставки определяется как точка, в которой ключ target будет вставлен в массив, т. е. индекс первого элемента больше ключа, или размер массива, если все элементы в массиве меньше указанного ключа. Затем сравните элементы вокруг точки вставки. i чтобы получить первый k ближайшие элементы. Временная сложность этого решения O(n), куда n это размер ввода.

Мы также можем найти точку вставки i с использованием алгоритм бинарного поиска, который работает в O(log(n)) время. С момента обнаружения k ближайший элемент занимает O(k) время, общая временная сложность этого решения равна O(log(n) + k). Ниже приведена реализация на C, C++, Java и Python, основанная на этой идее:

C

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

#include <stdio.h>

#include <stdlib.h>

// Функция для поиска в указанном массиве `nums` ключа `target`

// используя алгоритм бинарного поиска

int binarySearch(int nums[], int n, int target)

{

    int low = 0;

    int high = n 1;

    while (low <= high)

    {

        int mid = low + (high low) / 2;

        if (nums[mid] < target) {

            low = mid + 1;

        }

        else if (nums[mid] > target) {

            high = mid 1;

        }

        else {

            return mid;     // ключ найден

        }

    }

    return low;             // ключ не найден

}

// Функция для поиска `k` элементов, ближайших к `target`, в отсортированном целочисленном массиве `nums`

void findKClosestElements(int nums[], int target, int k, int n)

{

    // найти точку вставки с помощью алгоритма бинарного поиска

    int i = binarySearch(nums, n, target);

    int left = i 1;

    int right = i;

    // запустить `k` раз

    while (k > 0)

    {

        // сравниваем элементы по обе стороны от точки вставки `i`

        // чтобы получить первые `k` ближайших элементов

        if (left < 0 || (right < n &&

                abs(nums[left] target) > abs(nums[right] target))) {

            right++;

        }

        else {

            left;

        }

    }

    // вывести `k` ближайших элементов

    left++;

    while (left < right)

    {

        printf(“%d “, nums[left]);

        left++;

    }

}

int main(void)

{

    int nums[] = { 10, 12, 15, 17, 18, 20, 25 };

    int n = sizeof(nums) / sizeof(nums[0]);

    int target = 16, k = 4;

    findKClosestElements(nums, target, k, n);

    return 0;

}

Скачать  Выполнить код

результат:

12 15 17 18

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

// Функция для поиска `k` ближайших элементов к `target` в отсортированном целочисленном векторе `input`

vector<int> findKClosestElements(vector<int> const &input, int target, int k)

{

    // найти точку вставки с помощью алгоритма бинарного поиска

    int i = lower_bound(input.begin(), input.end(), target) input.begin();

    int left = i 1;

    int right = i;

    // запустить `k` раз

    while (k > 0)

    {

        // сравниваем элементы по обе стороны от точки вставки `i`

        // чтобы получить первые `k` ближайших элементов

        if (left < 0 || (right < input.size() &&

                abs(input[left] target) > abs(input[right] target))) {

            right++;

        }

        else {

            left;

        }

    }

    // вернуть `k` ближайших элементов

    return vector<int>(input.begin() + left + 1, input.begin() + right);

}

int main()

{

    vector<int> input = { 10, 12, 15, 17, 18, 20, 25 };

    int target = 16, k = 4;

    vector<int> result = findKClosestElements(input, target, k);

    for (int i: result) {

        cout << i << ” “;

    }

    return 0;

}

Скачать  Выполнить код

результат:

12 15 17 18

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

class Main

{

    // Функция для поиска `k` элементов, ближайших к `target`, в отсортированном списке `input`

    public static List<Integer> findKClosestElements(List<Integer> input, int k, int target)

    {

        // найти точку вставки с помощью алгоритма бинарного поиска

        int i = Collections.binarySearch(input, target);

        // Collections.binarySearch() возвращает `-(точка вставки) – 1`

        // если ключ не содержится в списке

        if (i < 0) {

            i = (i + 1);

        }

        int left = i 1;

        int right = i;

        // запустить `k` раз

        while (k > 0)

        {

            // сравниваем элементы по обе стороны от точки вставки `i`

            // чтобы получить первые `k` ближайших элементов

            if (left < 0 || (right < input.size() &&

                    Math.abs(input.get(left) target) > Math.abs(input.get(right) target))) {

                right++;

            }

            else {

                left;

            }

        }

        // вернуть `k` ближайших элементов

        return input.subList(left + 1, right);

    }

    public static void main(String[] args)

    {

        List<Integer> input = Arrays.asList(10, 12, 15, 17, 18, 20, 25);

        int target = 16, k = 4;

        System.out.println(findKClosestElements(input, k, target));

    }

}

Скачать  Выполнить код

результат:

[12, 15, 17, 18]

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

# Функция для поиска в указанном массиве `nums` ключа `target`

# с использованием алгоритма бинарного поиска

def binarySearch(nums, target):

    low = 0

    high = len(nums) 1

    while low <= high:

        mid = low + (high low) // 2

        if nums[mid] < target:

            low = mid + 1

        elif nums[mid] > target:

            high = mid 1

        else:

            return mid      # Ключ # найден

    return low              # Ключ # не найден

# Функция для поиска `k` элементов, ближайших к `target`, в отсортированном массиве целых чисел `nums`

def findKClosestElements(nums, target, k):

    # найти точку вставки с помощью алгоритма бинарного поиска

    i = binarySearch(nums, target)

    left = i 1

    right = i

    # запускается `k` раз

    while k > 0:

        # сравнить элементы по обе стороны от точки вставки `i`

        #, чтобы получить первые `k` ближайших элементов

        if left < 0 or (right < len(nums) and abs(nums[left] target) > abs(nums[right] target)):

            right = right + 1

        else:

            left = left 1

        k = k 1

    # возвращает `k` ближайших элементов

    return nums[left+1: right]

if __name__ == ‘__main__’:

    nums = [10, 12, 15, 17, 18, 20, 25]

    target = 16

    k = 4

    print(findKClosestElements(nums, target, k))

Скачать  Выполнить код

результат:

[12, 15, 17, 18]

Приведенное выше решение для выполнения двоичного поиска, чтобы найти точку вставки, а затем пытается найти k ближайшие элементы. Однако мы можем объединить всю логику в одну процедуру бинарного поиска. Вот как алгоритм будет выглядеть в C, Java и Python:

C

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

#include <stdio.h>

#include <stdlib.h>

// Функция для поиска `k` элементов, ближайших к `target`, в отсортированном целочисленном массиве `nums`

void findKClosestElements(int nums[], int target, int k, int n)

{

    int left = 0;

    int right = n;

    while (right left >= k)

    {

        if (abs(nums[left] target) > abs(nums[right] target)) {

            left++;

        }

        else {

            right;

        }

    }

    // вывести `k` ближайших элементов

    while (left <= right)

    {

        printf(“%d “, nums[left]);

        left++;

    }

}

int main(void)

{

    int nums[] = { 10, 12, 15, 17, 18, 20, 25 };

    int n = sizeof(nums) / sizeof(nums[0]);

    int target = 16, k = 4;

    findKClosestElements(nums, target, k, n);

    return 0;

}

Скачать  Выполнить код

результат:

12 15 17 18

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

class Main

{

    // Функция для поиска `k` элементов, ближайших к `target`, в отсортированном целочисленном массиве `nums`

    public static List<Integer> findKClosestElements(int[] nums, int k, int target)

    {

        int left = 0;

        int right = nums.length 1;

        while (right left >= k)

        {

            if (Math.abs(nums[left] target) > Math.abs(nums[right] target)) {

                left++;

            }

            else {

                right;

            }

        }

        return Arrays.stream(nums, left, right + 1).boxed()

                .collect(Collectors.toList());

    }

    public static void main(String[] args)

    {

        int[] nums = {10, 12, 15, 17, 18, 20, 25 };

        int target = 16, k = 4;

        System.out.println(findKClosestElements(nums, k, target));

    }

}

Скачать  Выполнить код

результат:

[12, 15, 17, 18]

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

# Функция для поиска `k` элементов, ближайших к `target`, в отсортированном массиве целых чисел `nums`

def findKClosestElements(nums, k, target):

    left = 0

    right = len(nums) 1

    while right left >= k:

        if abs(nums[left] target) > abs(nums[right] target):

            left = left + 1

        else:

            right = right 1

    return nums[left:left + k]

if __name__ == ‘__main__’:

    nums = [10, 12, 15, 17, 18, 20, 25]

    target = 16

    k = 4

    print(findKClosestElements(nums, k, target))

Скачать  Выполнить код

результат:

[12, 15, 17, 18]

Временная сложность приведенного выше решения равна O(n) и не требует дополнительного места.

zura87

1 / 1 / 0

Регистрация: 22.12.2012

Сообщений: 38

1

Как найти наиболее близкое число в массиве?

08.04.2019, 08:50. Показов 14615. Ответов 9

Метки наиболее близкое число (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте!

Есть массив

Javascript
1
 var a = [-6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932]

и есть число

Javascript
1
 var b = -620

Как выбрать максимально приближенное число в массиве?

если b = -620 из массива должно выбрать -648, если b = -180, тогда -220 и т. д.

Заранее спасибо!



1



arcmag

347 / 322 / 203

Регистрация: 27.06.2014

Сообщений: 762

08.04.2019, 10:35

2

Ну у меня как то так получилось, по вашему примеру вроде работает

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
const arr = [-6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932];
const searchNumber = -620;
 
const getNumber = (arr, number) =>
  arr.map(it => {
      const ch = (it >= 0 ? it : -it) + number;
      return {
        base: it,
        result: ch >= 0 ? ch : -ch
      };
    }).sort((a, b) => a.result - b.result)[0].base
 
console.log(getNumber(arr, searchNumber));



1



1 / 1 / 0

Регистрация: 22.12.2012

Сообщений: 38

08.04.2019, 11:29

 [ТС]

3

Огромное спасибо!
То что и было нужно !!!!!!



0



Mr_Sergo

Эксперт JS

2033 / 1092 / 408

Регистрация: 29.04.2016

Сообщений: 2,612

08.04.2019, 14:37

4

zura87, можно так еще

Javascript
1
2
3
4
5
6
let search = -620;
let arr = [-6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932];
 
console.log(
    arr.filter(cur => cur < search)[0]  // -648
);

или так но с положительными и отрицательными числами

Javascript
1
2
3
4
5
let search = 500;
let arr = [6, 220, 434, 648, 862, -1076, -1290, -1504, -1718, -1932];
let res = search < 0 ? arr.filter(cur => cur < search)[0] : arr.filter(cur => cur > search)[0];
 
console.log(res);



3



1 / 1 / 0

Регистрация: 22.12.2012

Сообщений: 38

08.04.2019, 14:38

 [ТС]

5

Спасибо, буду пробовать



0



arcmag

347 / 322 / 203

Регистрация: 27.06.2014

Сообщений: 762

08.04.2019, 15:55

6

Цитата
Сообщение от Mr_Sergo
Посмотреть сообщение

или так но с положительными и отрицательными числами

Интересный вариант, но результат какой то неожиданный немного.

Javascript
1
search = -42;
Javascript
1
console.log(res); // -1076

Хотя вроде бы должно быть 6, всё таки оно в более близком диапазоне…

Javascript
1
search = 221;
Javascript
1
console.log(res); // 434

Хотя 220 ближе



0



amr-now

Эксперт JS

6446 / 3893 / 2005

Регистрация: 14.06.2018

Сообщений: 6,781

08.04.2019, 16:17

7

zura87, arcmag, Mr_Sergo, а я чо-то не стал изобретать новые алгоритмы
и тупо применил один из методов LINQ.
Естественно, если скопировать библиотечную функцию, то код получается длинным.
Но логика то простая и понятная.

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        /**
         * Минимальный элемент массива или массивоподобного объекта. Адаптация из LINQ
         * @param {Array} array Входящий массив.
         * @param {Function} selector Функция, возвращающая из объекта свойство, по которому надо искать минимальный элемент
         */
        function min(array, /*Func<TSource, TResult>*/ selector) {
            let res, v, v2, count = array.length;
            if (selector)
                for (let i = 0; i < count; ++i) {
                    v = array[i];
                    v2 = selector(v);
                    if (!isNaN(v2)) {
                        if (res === undefined || v2 < res)
                            res = v2;
                    }
                }
            else
                for (let i = 0; i < count; ++i) {
                    v = array[i];
                    if (!isNaN(v)) {
                        if (res === undefined || v < res)
                            res = v;
                    }
                }
            if (!isNaN(res))
                return res;
            throw new Error("No elements");
        }
 
        let a = [-6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932],
            b = -42; //-620;
        let diff = min(a, e => Math.abs(e - b));
 
        console.log(a.find(e => Math.abs(e - b) === diff));



2



arcmag

347 / 322 / 203

Регистрация: 27.06.2014

Сообщений: 762

08.04.2019, 17:16

8

Лучший ответ Сообщение было отмечено zura87 как решение

Решение

amr-now,
Взял на себя смелость чуток сократить… пример хороший кстати, работает получше моего первого

Javascript
1
2
3
4
5
6
const getNumber = (arr, searchNumer) => 
  arr.find(it => Math.abs(it - searchNum) === Math.min(...arr.map(it => Math.abs(it - searchNum))));
 
const arr = [123, 23, -6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932];
const searchNum = 9;
console.log(getNumber(arr, searchNum));



3



Qwerty_Wasd

dev – investigator

Эксперт JSЭксперт HTML/CSS

2148 / 1493 / 651

Регистрация: 16.04.2016

Сообщений: 3,696

08.04.2019, 17:30

9

Ну и до кучи )))

Javascript
1
2
let a = [-6, -220, -434, -648, -862, -1076, -1290, -1504, -1718, -1932], b = -620;
console.log(a.sort((x, y) => Math.abs(b - x) - Math.abs(b - y) )[0]);



4



1 / 1 / 0

Регистрация: 22.12.2012

Сообщений: 38

09.04.2019, 10:28

 [ТС]

10

Всем спасибо, очень помогли.



0



Учитывая отсортированный массив arr [] и значение X, найдите k ближайших к X элементов в arr [].
Примеры:

Input: K = 4, X = 35
       arr[] = {12, 16, 22, 30, 35, 39, 42, 
               45, 48, 50, 53, 55, 56}
Output: 30 39 42 45

Обратите внимание, что если элемент присутствует в массиве, то он не должен быть в выводе, требуются только другие ближайшие элементы.

В следующих решениях предполагается, что все элементы массива различны.

Простым решением является линейный поиск k ближайших элементов.
1) Начните с первого элемента и найдите точку пересечения (точка, до которой элементы меньше или равны X и после которых элементы больше). Этот шаг занимает O (N) времени.
2) Как только мы находим точку пересечения, мы можем сравнить элементы по обе стороны от точки пересечения, чтобы вывести k ближайших элементов. Этот шаг занимает O (K) времени.

Временная сложность вышеуказанного решения составляет O (n).

Оптимизированное решение — найти k элементов за O (Logn + k) времени. Идея состоит в том, чтобы использовать двоичный поиск, чтобы найти точку пересечения. Как только мы находим индекс точки пересечения, мы можем вывести k ближайших элементов за O (k) время.

C / C ++

#include<stdio.h>

int findCrossOver(int arr[], int low, int high, int x)

{

  if (arr[high] <= x)

    return high;

  if (arr[low] > x) 

    return low;

  int mid = (low + high)/2; 

  if (arr[mid] <= x && arr[mid+1] > x)

    return mid;

  if(arr[mid] < x)

      return findCrossOver(arr, mid+1, high, x);

  return findCrossOver(arr, low, mid - 1, x);

}

void printKclosest(int arr[], int x, int k, int n)

{

    int l = findCrossOver(arr, 0, n-1, x);

    int r = l+1;  

    int count = 0;

    if (arr[l] == x) l--;

    while (l >= 0 && r < n && count < k)

    {

        if (x - arr[l] < arr[r] - x)

            printf("%d ", arr[l--]);

        else

            printf("%d ", arr[r++]);

        count++;

    }

    while (count < k && l >= 0)

        printf("%d ", arr[l--]), count++;

    while (count < k && r < n)

        printf("%d ", arr[r++]), count++;

}

int main()

{

   int arr[] ={12, 16, 22, 30, 35, 39, 42,

               45, 48, 50, 53, 55, 56};

   int n = sizeof(arr)/sizeof(arr[0]);

   int x = 35, k = 4;

   printKclosest(arr, x, 4, n);

   return 0;

}

Джава

class KClosest

{

    int findCrossOver(int arr[], int low, int high, int x)

    {

        if (arr[high] <= x)

            return high;

        if (arr[low] > x) 

            return low;

        int mid = (low + high)/2

        if (arr[mid] <= x && arr[mid+1] > x)

            return mid;

        if(arr[mid] < x)

            return findCrossOver(arr, mid+1, high, x);

        return findCrossOver(arr, low, mid - 1, x);

    }

    void printKclosest(int arr[], int x, int k, int n)

    {

        int l = findCrossOver(arr, 0, n-1, x); 

        int r = l+1;  

        int count = 0;

        if (arr[l] == x) l--;

        while (l >= 0 && r < n && count < k)

        {

            if (x - arr[l] < arr[r] - x)

                System.out.print(arr[l--]+" ");

            else

                System.out.print(arr[r++]+" ");

            count++;

        }

        while (count < k && l >= 0)

        {

            System.out.print(arr[l--]+" ");

            count++;

        }

        while (count < k && r < n)

        {

            System.out.print(arr[r++]+" ");

            count++;

        }

    }

    public static void main(String args[])

    {

        KClosest ob = new KClosest();

        int arr[] = {12, 16, 22, 30, 35, 39, 42,

                     45, 48, 50, 53, 55, 56

                    };

        int n = arr.length;

        int x = 35, k = 4;

        ob.printKclosest(arr, x, 4, n);

    }

}

python3

def findCrossOver(arr, low, high, x) : 

    if (arr[high] <= x) :

        return high

    if (arr[low] > x) :

        return low 

    mid = (low + high) // 2

    if (arr[mid] <= x and arr[mid + 1] > x) :

        return mid 

    if(arr[mid] < x) :

        return findCrossOver(arr, mid + 1, high, x)

    return findCrossOver(arr, low, mid - 1, x)

def printKclosest(arr, x, k, n) :

    l = findCrossOver(arr, 0, n - 1, x)

    r = l + 1

    count = 0

    if (arr[l] == x) :

        l -= 1

    while (l >= 0 and r < n and count < k) :

        if (x - arr[l] < arr[r] - x) :

            print(arr[l], end = " "

            l -= 1

        else :

            print(arr[r], end = " "

            r += 1

        count += 1

    while (count < k and l >= 0) :

        print(arr[l], end = " ")

        l -= 1

        count += 1

    while (count < k and r < n) : 

        print(arr[r], end = " ")

        r += 1

        count += 1

if __name__ == "__main__" :

    arr =[12, 16, 22, 30, 35, 39, 42

              45, 48, 50, 53, 55, 56]

    n = len(arr)

    x = 35

    k = 4

    printKclosest(arr, x, 4, n)

C #

using System;

class GFG {

    static int findCrossOver(int []arr, int low,

                                int high, int x)

    {

        if (arr[high] <= x)

            return high;

        if (arr[low] > x) 

            return low;

        int mid = (low + high)/2; 

        if (arr[mid] <= x && arr[mid+1] > x)

            return mid;

        if(arr[mid] < x)

            return findCrossOver(arr, mid+1, 

                                      high, x);

        return findCrossOver(arr, low, mid - 1, x);

    }

    static void printKclosest(int []arr, int x,

                                  int k, int n)

    {

        int l = findCrossOver(arr, 0, n-1, x); 

        int r = l + 1; 

        int count = 0; 

        if (arr[l] == x) l--;

        while (l >= 0 && r < n && count < k)

        {

            if (x - arr[l] < arr[r] - x)

                Console.Write(arr[l--]+" ");

            else

                Console.Write(arr[r++]+" ");

            count++;

        }

        while (count < k && l >= 0)

        {

            Console.Write(arr[l--]+" ");

            count++;

        }

        while (count < k && r < n)

        {

            Console.Write(arr[r++] + " ");

            count++;

        }

    }

    public static void Main()

    {

        int []arr = {12, 16, 22, 30, 35, 39, 42,

                         45, 48, 50, 53, 55, 56};

        int n = arr.Length;

        int x = 35;

        printKclosest(arr, x, 4, n);

    }

}

PHP

<?php

function findCrossOver($arr, $low

                       $high, $x)

{

    if ($arr[$high] <= $x

        return $high;

    if ($arr[$low] > $x

        return $low;

    $mid = ($low + $high)/2; 

    if ($arr[$mid] <= $x and

        $arr[$mid + 1] > $x)

        return $mid;

    if($arr[$mid] < $x)

        return findCrossOver($arr, $mid + 1, 

                                 $high, $x);

    return findCrossOver($arr, $low,

                      $mid - 1, $x);

}

function printKclosest($arr, $x, $k, $n)

{

    $l = findCrossOver($arr, 0, $n - 1, $x);

    $r = $l + 1;

    $count = 0; 

    if ($arr[$l] == $x) $l--;

    while ($l >= 0 and $r < $n 

              and $count < $k)

    {

        if ($x - $arr[$l] < $arr[$r] - $x)

            echo $arr[$l--]," ";

        else

            echo $arr[$r++]," ";

        $count++;

    }

    while ($count < $k and $l >= 0)

        echo $arr[$l--]," "; $count++;

    while ($count < $k and $r < $n)

        echo $arr[$r++]; $count++;

}

$arr =array(12, 16, 22, 30, 35, 39, 42,

                45, 48, 50, 53, 55, 56);

$n = count($arr);

$x = 35; $k = 4;

printKclosest($arr, $x, 4, $n);

  

?>

Выход:

39 30 42 45

Временная сложность этого метода составляет O (Logn + k).

Упражнение: Расширение оптимизированного решения для работы и для дубликатов, т. Е. Для работы с массивами, где элементы не должны быть различимыми.

Эта статья пополняемая Рахул Джейна. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

  • Найти три ближайших элемента из заданных трех отсортированных массивов
  • Два элемента, сумма которых ближе всего к нулю
  • Найти подмассив с суммой, ближайшей к 0
  • Найти ближайший номер в массиве
  • Найти ближайшее значение для каждого элемента в массиве
  • Найти ближайшую пару из двух отсортированных массивов
  • Найти k ближайших чисел в несортированном массиве
  • Найти ближайшее большее значение для каждого элемента в массиве
  • Найти ближайшее меньшее значение для каждого элемента в массиве
  • Найти триплет в массиве, сумма которого ближе всего к данному числу
  • Найти ближайший элемент в дереве бинарного поиска
  • Учитывая отсортированный массив и число x, найдите пару в массиве, сумма которой ближе всего к x
  • Найти элементы больше, чем половина элементов в массиве
  • Найти элемент Kth в массиве, содержащем сначала нечетные элементы, а затем четные элементы
  • Найти все элементы в массиве, которые имеют как минимум два больших элемента

Найти k ближайших элементов к заданному значению

0.00 (0%) 0 votes

Добавить комментарий