План курса / Все задачи / Алгоритмы и структуры данных
Поиск в 2D массиве
средне
# решено
Дан двумерный массив matrix размером n x m, где каждая строка отсортирована в монотонно возрастающем порядке, а первый элемент каждой строки строго больше последнего элемента предыдущей строки. Также дано число target. Нужно вернуть true, если target присутствует в matrix, и false в противном случае.
public class Solution
{
// Получаем значение в 2D массиве по одному индексу,
// чтобы бинарный поиск был аналогичен поиску в 1D массиве
public static int ElementFromMatrix(List<List<int>> matrix, int index)
{
int n = matrix[0].Count; // Количество столбцов в матрице
return matrix[index / n][index % n];
}
// Бинарный поиск как для 1D массива
public static bool Search(List<List<int>> matrix, int target)
{
if (matrix.Count == 0 || matrix[0].Count == 0)
{
return false; // Если матрица пустая, возвращаем false
}
int left = 0;
int right = matrix.Count * matrix[0].Count; // Общее количество элементов в матрице
while (right - left > 1)
{
int mid = (left + right) / 2;
if (ElementFromMatrix(matrix, mid) <= target)
{
left = mid;
}
else
{
right = mid;
}
}
return ElementFromMatrix(matrix, left) == target;
}
}
#include <vector>
using namespace std;
int elementFromMatrix(const vector<vector<int>>& matrix, int i) {
// получаем значение в 2D массиве по одному индексу,
// чтобы бинарный поиск был аналогичен поиску в 1D массиве
int n = matrix[0].size();
return matrix[i / n][i % n];
}
bool search(const vector<vector<int>>& matrix, int target) {
// бинарный поиск как для 1D массива
int l = 0, r = matrix.size() * matrix[0].size();
while (r - l > 1) {
int m = (l + r) / 2;
if (elementFromMatrix(matrix, m) <= target) {
l = m;
} else {
r = m;
}
}
return elementFromMatrix(matrix, l) == target;
}
package main
func elementFromMatrix(matrix [][]int, i int) int {
// получаем значение в 2D массиве по одному индексу,
// чтобы бинарный поиск был аналогичен поиску в 1D массиве
n := len(matrix[0])
return matrix[i/n][i%n]
}
func search(matrix [][]int, target int) bool {
// бинарный поиск как для 1D массива
l, r := 0, len(matrix)*len(matrix[0])
for r-l > 1 {
m := (l + r) / 2
if elementFromMatrix(matrix, m) <= target {
l = m
} else {
r = m
}
}
return elementFromMatrix(matrix, l) == target
}
import java.util.List;
public class Solution {
public int elementFromMatrix(List<List<Integer>> matrix, int i) {
// получаем значение в 2D списке по одному индексу,
// чтобы бинарный поиск был аналогичен поиску в 1D массиве
int n = matrix.get(0).size();
return matrix.get(i / n).get(i % n);
}
public boolean search(List<List<Integer>> matrix, int target) {
// бинарный поиск как для 1D списка
int l = 0, r = matrix.size() * matrix.get(0).size();
while (r - l > 1) {
int m = (l + r) / 2;
if (elementFromMatrix(matrix, m) <= target) {
l = m;
} else {
r = m;
}
}
return elementFromMatrix(matrix, l) == target;
}
}
from typing import *
def element_from_matrix(matrix: List[List[int]], i: int):
# получаем значение в 2D массиве, по одному индексу,
# чтобы бинарный поиск был аналогичен поиску в 1D массиве
n = len(matrix[0])
return matrix[i // n][i % n]
def search(matrix: List[List[int]], target: int) -> bool:
# бинарный поиск как для 1D массива
l, r = 0, len(matrix) * len(matrix[0])
while r - l > 1:
m = (l + r) // 2
if element_from_matrix(matrix, m) <= target:
l = m
else:
r = m
return element_from_matrix(matrix, l) == target
function elementFromMatrix(matrix, i) {
// получаем значение в 2D массиве, по одному индексу,
// чтобы бинарный поиск был аналогичен поиску в 1D массиве
const n = matrix[0].length;
return matrix[Math.floor(i / n)][i % n];
}
export function search(matrix, target) {
// бинарный поиск как для 1D массива
let l = 0;
let r = matrix.length * matrix[0].length;
while (r - l > 1) {
const m = Math.floor((l + r) / 2);
if (elementFromMatrix(matrix, m) <= target) {
l = m;
} else {
r = m;
}
}
return elementFromMatrix(matrix, l) === target;
}
Оценка сложности
Время: O(log(n)), где n - число всех элементов в массиве matrix