-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpartially_sorted_matrix.cpp
142 lines (121 loc) · 4.73 KB
/
partially_sorted_matrix.cpp
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
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Matrix Value Search
*
* Given a matrix where each row and each column is sorted in ascending order,
* the goal is to determine if a given target value exists within the matrix.
*
* Constraints and Expectations:
* - Each row is sorted left-to-right.
* - Each column is sorted top-to-bottom.
* - The task is to implement two solutions:
* 1. A Simple (Divide and Conquer) Approach: Uses recursion to narrow down the search space.
* 2. An Optimal (Staircase) Approach: Iteratively searches from the top-right corner.
* - An alternative brute-force solution is also provided for educational comparison.
*
* ASCII Illustration of the Matrix:
* +----+----+----+----+
* | 1 | 2 | 8 | 9 |
* +----+----+----+----+
* | 2 | 4 | 9 | 12 |
* +----+----+----+----+
* | 4 | 7 | 10 | 13 |
* +----+----+----+----+
* | 6 | 8 | 11 | 15 |
* +----+----+----+----+
*
* Example:
* Input: Matrix as shown above, Target = 7
* Output: true
* Explanation: The value 7 is located at row 3, column 2 (0-indexed) of the matrix.
*/
#include <algorithm>
#include <cassert>
#include <vector>
#include <iostream>
// Simple (Divide and Conquer) Solution
// Recursive approach: divides the matrix into submatrices based on the middle element.
// Average complexity may be better than brute-force, though worst-case may involve overlapping searches.
bool simpleSolutionHelper(const std::vector<std::vector<int>>& matrix, int value,
int row1, int col1, int row2, int col2) {
if (row1 > row2 || col1 > col2)
return false;
// If target is outside the current submatrix's range, skip search.
if (value < matrix[row1][col1] || value > matrix[row2][col2])
return false;
// Directly check boundaries.
if (value == matrix[row1][col1] || value == matrix[row2][col2])
return true;
int midRow = (row1 + row2) / 2;
int midCol = (col1 + col2) / 2;
if (matrix[midRow][midCol] == value)
return true;
// If target is less than middle element, it could be in the top-left quadrant.
if (value < matrix[midRow][midCol])
return simpleSolutionHelper(matrix, value, row1, col1, midRow, midCol);
// Otherwise, check the bottom and right submatrices.
return simpleSolutionHelper(matrix, value, midRow + 1, col1, row2, midCol) ||
simpleSolutionHelper(matrix, value, row1, midCol + 1, midRow, col2);
}
bool simpleSolution(const std::vector<std::vector<int>>& matrix, int value) {
if(matrix.empty() || matrix.front().empty())
return false;
return simpleSolutionHelper(matrix, value, 0, 0,
static_cast<int>(matrix.size()) - 1,
static_cast<int>(matrix[0].size()) - 1);
}
// Optimal (Staircase) Solution
// Iterative approach starting from the top-right corner, reducing the search space at each step.
// Complexity: O(n + m), where n is the number of rows and m is the number of columns.
bool optimalSolution(const std::vector<std::vector<int>>& matrix, int value) {
if (matrix.empty() || matrix.front().empty())
return false;
int rows = matrix.size(), cols = matrix[0].size();
int row = 0, col = cols - 1;
while (row < rows && col >= 0) {
if (matrix[row][col] == value)
return true;
else if (matrix[row][col] > value)
--col;
else
++row;
}
return false;
}
// (Optional) Alternative Solution
// Brute-force search for educational purposes. Complexity: O(n * m)
bool alternativeSolution(const std::vector<std::vector<int>>& matrix, int value) {
for (const auto& row : matrix)
for (const auto& elem : row)
if (elem == value)
return true;
return false;
}
// Test cases for correctness
void test() {
std::vector<std::vector<int>> matrix{
{1, 2, 8, 9},
{2, 4, 9, 12},
{4, 7, 10, 13},
{6, 8, 11, 15}
};
// Test for a value that exists in the matrix.
assert(simpleSolution(matrix, 7) == true);
assert(optimalSolution(matrix, 7) == true);
assert(alternativeSolution(matrix, 7) == true);
// Test for a value that does not exist.
assert(simpleSolution(matrix, 5) == false);
assert(optimalSolution(matrix, 5) == false);
assert(alternativeSolution(matrix, 5) == false);
// Test boundaries.
assert(simpleSolution(matrix, 1) == true);
assert(optimalSolution(matrix, 1) == true);
assert(alternativeSolution(matrix, 1) == true);
assert(simpleSolution(matrix, 15) == true);
assert(optimalSolution(matrix, 15) == true);
assert(alternativeSolution(matrix, 15) == true);
std::cout << "All tests passed!\n";
}
int main() {
test();
return 0;
}