-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathMatrixSearch.java
129 lines (115 loc) · 4.66 KB
/
MatrixSearch.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.interviewbit.binary_search;
import com.util.LogUtil;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* https://www.interviewbit.com/problems/matrix-search/
* <p>
* Write an efficient algorithm that searches for a value in an m x n matrix.
* <p>
* This matrix has the following properties:
* <p>
* Integers in each row are sorted from left to right.
* The first integer of each row is greater than or equal to the last integer of the previous row.
* Example:
* <p>
* Consider the following matrix:
* <p>
* [
* [1, 3, 5, 7],
* [10, 11, 16, 20],
* [23, 30, 34, 50]
* ]
* Given target = 3, return 1 ( 1 corresponds to true )
* <p>
* Return 0 / 1 ( 0 if the element is not present, 1 if the element is present ) for this problem
*
* @author neeraj on 2019-07-29
* Copyright (c) 2019, data-structures.
* All rights reserved.
*/
public class MatrixSearch {
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> a = new ArrayList<>();
ArrayList<Integer> row1 = new ArrayList<>(Arrays.asList(1, 3, 5, 7));
ArrayList<Integer> row2 = new ArrayList<>(Arrays.asList(10, 11, 16, 20));
ArrayList<Integer> row3 = new ArrayList<>(Arrays.asList(23, 30, 34, 50));
a.add(row1);
a.add(row2);
a.add(row3);
// System.out.println(searchMatrix(a, 1));
// System.out.println(searchMatrix(a, 3));
// System.out.println(searchMatrix(a, 5));
// System.out.println(searchMatrix(a, 7));
// System.out.println(searchMatrix(a, 10));
// System.out.println(searchMatrix(a, 11));
// System.out.println(searchMatrix(a, 16));
// System.out.println(searchMatrix(a, 20));
// System.out.println(searchMatrix(a, 23));
// System.out.println(searchMatrix(a, 30));
// System.out.println(searchMatrix(a, 34));
// System.out.println(searchMatrix(a, 50));
// System.out.println(searchMatrix(a, 51));
ArrayList<ArrayList<Integer>> b = new ArrayList<>();
ArrayList<Integer> rowB1 = new ArrayList<>(Arrays.asList(1, 4, 7, 11, 15));
ArrayList<Integer> rowB2 = new ArrayList<>(Arrays.asList(2, 5, 8, 12, 19));
ArrayList<Integer> rowB3 = new ArrayList<>(Arrays.asList(3, 6, 9, 16, 22));
ArrayList<Integer> rowB4 = new ArrayList<>(Arrays.asList(10, 13, 14, 17, 24));
ArrayList<Integer> rowB5 = new ArrayList<>(Arrays.asList(18, 21, 23, 26, 30));
b.add(rowB1);
b.add(rowB2);
b.add(rowB3);
b.add(rowB4);
b.add(rowB5);
System.out.println(searchMatrix(b, 5));
}
public static int searchMatrix(ArrayList<ArrayList<Integer>> a, int b) {
/**
* A) First identify the row in which value might be present
* a) this we can do in O(Log(N)) time by performing binary search based on the first index of each row
* B) Once we have the row, it's again O(Log(N)) time to go through that row and find out the item
*/
int possibleRow = findPossibleRowContainingTheValue(a, b, 0, a.size()-1);
if (possibleRow != -1) {
LogUtil.logIt("Possible Row is "+ possibleRow);
return binarySearch(a.get(possibleRow), 0, a.get(possibleRow).size()-1, b);
} else {
return 0;
}
}
public static int binarySearch(ArrayList<Integer> arr, int low, int high, int value) {
if (low <= high) {
int mid = low + (high - low) / 2;
if (arr.get(mid) == value) {
return 1;
} else if (arr.get(mid) > value) {
return binarySearch(arr, low, mid - 1, value);
} else {
return binarySearch(arr, mid + 1, high, value);
}
} else {
return 0;
}
}
public static int findPossibleRowContainingTheValue(ArrayList<ArrayList<Integer>> arr, int valueWeAreSearching, int low, int high) {
if (low <= high) {
if (low == high) {
return low;
}
int mid = low + (high - low) / 2;
List<Integer> middleRow = arr.get(mid);
if (middleRow.get(0) <= valueWeAreSearching) {
if (middleRow.get(middleRow.size() - 1) >= valueWeAreSearching) {
return mid;
} else {
return findPossibleRowContainingTheValue(arr, valueWeAreSearching, mid + 1, high);
}
} else if (middleRow.get(0) > valueWeAreSearching) {
return findPossibleRowContainingTheValue(arr, valueWeAreSearching, low, mid - 1);
}
}
return -1;
}
}