|
1 | 1 | package com.thealgorithms.searches;
|
2 | 2 |
|
3 |
| -/* |
4 |
| -To apply this method, the provided array must be strictly sorted. In this method, two pointers, one |
5 |
| -at 0th row & the other at the last row are taken & the searching is done on the basis of the middle |
6 |
| -element of the middle column. If that element is equal to target, its coordinates are returned, else |
7 |
| -if it is smaller than the target, the rows above that element are ignored (because the elements |
8 |
| -above it will also be smaller than the target), else that element is greater than the target, then |
9 |
| -the rows below it are ignored. |
| 3 | +/** |
| 4 | + * This class provides a method to search for a target value in a 2D sorted |
| 5 | + * array. |
| 6 | + * The search is performed using a combination of binary search on rows and |
| 7 | + * columns. |
| 8 | + * The 2D array must be strictly sorted in both rows and columns. |
| 9 | + * |
| 10 | + * The algorithm works by: |
| 11 | + * 1. Performing a binary search on the middle column of the 2D array. |
| 12 | + * 2. Depending on the value found, it eliminates rows above or below the middle |
| 13 | + * element. |
| 14 | + * 3. After finding or eliminating rows, it further applies binary search in the |
| 15 | + * relevant columns. |
10 | 16 | */
|
11 | 17 | public final class BinarySearch2dArray {
|
| 18 | + |
12 | 19 | private BinarySearch2dArray() {
|
13 | 20 | }
|
14 | 21 |
|
| 22 | + /** |
| 23 | + * Performs a binary search on a 2D sorted array to find the target value. |
| 24 | + * The array must be sorted in ascending order in both rows and columns. |
| 25 | + * |
| 26 | + * @param arr The 2D array to search in. |
| 27 | + * @param target The value to search for. |
| 28 | + * @return An array containing the row and column indices of the target, or [-1, |
| 29 | + * -1] if the target is not found. |
| 30 | + */ |
15 | 31 | static int[] binarySearch(int[][] arr, int target) {
|
16 | 32 | int rowCount = arr.length;
|
17 | 33 | int colCount = arr[0].length;
|
18 | 34 |
|
| 35 | + // Edge case: If there's only one row, search that row directly. |
19 | 36 | if (rowCount == 1) {
|
20 | 37 | return binarySearch(arr, target, 0, 0, colCount);
|
21 | 38 | }
|
22 | 39 |
|
| 40 | + // Set initial boundaries for binary search on rows. |
23 | 41 | int startRow = 0;
|
24 | 42 | int endRow = rowCount - 1;
|
25 |
| - int midCol = colCount / 2; |
| 43 | + int midCol = colCount / 2; // Middle column index for comparison. |
26 | 44 |
|
| 45 | + // Perform binary search on rows based on the middle column. |
27 | 46 | while (startRow < endRow - 1) {
|
28 |
| - int midRow = startRow + (endRow - startRow) / 2; // getting the index of middle row |
| 47 | + int midRow = startRow + (endRow - startRow) / 2; |
29 | 48 |
|
| 49 | + // If the middle element matches the target, return its position. |
30 | 50 | if (arr[midRow][midCol] == target) {
|
31 | 51 | return new int[] {midRow, midCol};
|
32 |
| - } else if (arr[midRow][midCol] < target) { |
| 52 | + } |
| 53 | + // If the middle element is smaller than the target, discard the upper half. |
| 54 | + else if (arr[midRow][midCol] < target) { |
33 | 55 | startRow = midRow;
|
34 |
| - } else { |
| 56 | + } |
| 57 | + // If the middle element is larger than the target, discard the lower half. |
| 58 | + else { |
35 | 59 | endRow = midRow;
|
36 | 60 | }
|
37 | 61 | }
|
38 |
| - /* |
39 |
| - if the above search fails to find the target element, these conditions will be used to |
40 |
| - find the target element, which further uses the binary search algorithm in the places |
41 |
| - which were left unexplored. |
42 |
| - */ |
| 62 | + |
| 63 | + // If the target wasn't found during the row search, check the middle column of |
| 64 | + // startRow and endRow. |
43 | 65 | if (arr[startRow][midCol] == target) {
|
44 |
| - return new int[] { |
45 |
| - startRow, |
46 |
| - midCol, |
47 |
| - }; |
| 66 | + return new int[] {startRow, midCol}; |
48 | 67 | }
|
49 | 68 |
|
50 | 69 | if (arr[endRow][midCol] == target) {
|
51 | 70 | return new int[] {endRow, midCol};
|
52 | 71 | }
|
53 | 72 |
|
| 73 | + // If target is smaller than the element in the left of startRow, perform a |
| 74 | + // binary search on the left of startRow. |
54 | 75 | if (target <= arr[startRow][midCol - 1]) {
|
55 | 76 | return binarySearch(arr, target, startRow, 0, midCol - 1);
|
56 | 77 | }
|
57 | 78 |
|
| 79 | + // If target is between midCol and the last column of startRow, perform a binary |
| 80 | + // search on that part of the row. |
58 | 81 | if (target >= arr[startRow][midCol + 1] && target <= arr[startRow][colCount - 1]) {
|
59 | 82 | return binarySearch(arr, target, startRow, midCol + 1, colCount - 1);
|
60 | 83 | }
|
61 | 84 |
|
| 85 | + // If target is smaller than the element in the left of endRow, perform a binary |
| 86 | + // search on the left of endRow. |
62 | 87 | if (target <= arr[endRow][midCol - 1]) {
|
63 | 88 | return binarySearch(arr, target, endRow, 0, midCol - 1);
|
64 | 89 | } else {
|
| 90 | + // Otherwise, search on the right of endRow. |
65 | 91 | return binarySearch(arr, target, endRow, midCol + 1, colCount - 1);
|
66 | 92 | }
|
67 | 93 | }
|
68 | 94 |
|
| 95 | + /** |
| 96 | + * Performs a binary search on a specific row of the 2D array. |
| 97 | + * |
| 98 | + * @param arr The 2D array to search in. |
| 99 | + * @param target The value to search for. |
| 100 | + * @param row The row index where the target will be searched. |
| 101 | + * @param colStart The starting column index for the search. |
| 102 | + * @param colEnd The ending column index for the search. |
| 103 | + * @return An array containing the row and column indices of the target, or [-1, |
| 104 | + * -1] if the target is not found. |
| 105 | + */ |
69 | 106 | static int[] binarySearch(int[][] arr, int target, int row, int colStart, int colEnd) {
|
| 107 | + // Perform binary search within the specified column range. |
70 | 108 | while (colStart <= colEnd) {
|
71 | 109 | int midIndex = colStart + (colEnd - colStart) / 2;
|
72 | 110 |
|
| 111 | + // If the middle element matches the target, return its position. |
73 | 112 | if (arr[row][midIndex] == target) {
|
74 |
| - return new int[] { |
75 |
| - row, |
76 |
| - midIndex, |
77 |
| - }; |
78 |
| - } else if (arr[row][midIndex] < target) { |
| 113 | + return new int[] {row, midIndex}; |
| 114 | + } |
| 115 | + // If the middle element is smaller than the target, move to the right half. |
| 116 | + else if (arr[row][midIndex] < target) { |
79 | 117 | colStart = midIndex + 1;
|
80 |
| - } else { |
| 118 | + } |
| 119 | + // If the middle element is larger than the target, move to the left half. |
| 120 | + else { |
81 | 121 | colEnd = midIndex - 1;
|
82 | 122 | }
|
83 | 123 | }
|
84 | 124 |
|
85 |
| - return new int[] {-1, -1}; |
| 125 | + return new int[] {-1, -1}; // Target not found |
86 | 126 | }
|
87 | 127 | }
|
0 commit comments