Форум программистов, компьютерный форум, киберфорум
Python: Решение задач
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56

Найдите кратчайший чистый путь от левого верхнего угла до правого нижнего угла матрицы

22.06.2023, 18:59. Показов 1629. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Решал задачу на литкоде, написал код, но он выполняется слишком медленно и падает из-за ограничения по времени на одном из тестов (пометил его в коде, как FIXME). Искал решения, похожие на мои, но не нашел. Каким образом можно оптимизировать программу?

Условие задачи: Дана матрица "grid" размером n x n (len(grid) == len(grid[i])). Найдите кротчайший чистый путь от левого верхнего угла (0, 0) до правого нижнего угла (n - 1, n - 1). Чистым путем считается путь, который состоит только из нулей. Если чистый путь найти невозможно, функция должна вернуть -1.

Примеры:
1. Ввод: Solution().shortest_path_binary_matrix([[0, 1], [1, 0]])
Вывод: 2

2. Ввод: Solution().shortest_path_binary_matrix([[0, 0, 0], [1, 1, 0], [1, 1, 0]])
Вывод: 4

3. Ввод: Solution().shortest_path_binary_matrix([[1, 0, 0], [1, 1, 0], [1, 1, 0]])
Вывод: -1

Моё решение:
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
class Solution:
 
    def shortest_path_binary_matrix(self,
                                    grid: list[list[int, ...]],
                                    __checked: list[tuple, ...] = None,
                                    __row: int = 0,
                                    __col: int = 0,
                                    __calls_num: int = 1) -> int:
 
        n = len(grid) - 1
        if (__row, __col) == (n, n):
            return __calls_num
 
        if __checked is None:
            __checked = [(0, 0)]
 
        possible_ways = [(row, col) for row in range(__row - 1, __row + 2) for col in range(__col - 1, __col + 2)
                         if (row, col) not in __checked and 0 <= row <= n and 0 <= col <= n and 0 == grid[row][col]]
 
        if not possible_ways or grid[0][0] != 0:
            return -1
 
        results = []
        for row, col in possible_ways:
            results.append(self.shortest_path_binary_matrix(grid, __checked + [(row, col)], row, col, __calls_num + 1))
        try:
            return min(tuple(filter(lambda x: x >= 0, results)))
        except ValueError:
            return -1

Тесты:
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
def test():
    assert Solution().shortest_path_binary_matrix([[0, 1],
                                                   [1, 0]]) == 2
 
    assert Solution().shortest_path_binary_matrix([[0, 0, 0],
                                                   [1, 1, 0],
                                                   [1, 1, 0]]) == 4
 
    assert Solution().shortest_path_binary_matrix([[1, 0, 0],
                                                   [1, 1, 0],
                                                   [1, 1, 0]]) == -1
 
    assert Solution().shortest_path_binary_matrix([[1, 0, 0],
                                                   [0, 0, 0],
                                                   [0, 0, 0]]) == -1
 
    assert Solution().shortest_path_binary_matrix([[0, 0, 0],
                                                   [0, 0, 0],
                                                   [0, 0, 0]]) == 3
 
    # FIXME: этот тест выполняется очень долго
    assert Solution().shortest_path_binary_matrix([[0, 0, 1, 1, 0, 0],
                                                   [0, 0, 0, 0, 1, 1],
                                                   [1, 0, 1, 1, 0, 0],
                                                   [0, 0, 1, 1, 0, 0],
                                                   [0, 0, 0, 0, 0, 0],
                                                   [0, 0, 1, 0, 0, 0]]) == 8
 
 
if __name__ == '__main__':
    test()
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.06.2023, 18:59
Ответы с готовыми решениями:

2. На диагонали (от правого верхнего угла до левого нижнего угла) матрицы действительных чисел А размера mxm (m=10) найт
2. На диагонали (от правого верхнего угла до левого нижнего угла) матрицы действительных чисел А размера mxm (m=10) найти все положительные...

2. На диагонали (от правого верхнего угла до левого нижнего угла) матрицы действительных чисел А размера mxm (m=10) найт
2. На диагонали (от правого верхнего угла до левого нижнего угла) матрицы действительных чисел А размера mxm (m=10) найти все положительные...

Нарисовать движущуюся от левого нижнего угла экрана до правого верхнего угла окружность
Нарисовать, движущуюся от левого нижнего угла экрана до правого верхнего угла, окружность.Создавайте темы с осмысленными и понятными...

8
Йуный плагиат-падаван)
176 / 119 / 45
Регистрация: 17.10.2022
Сообщений: 566
23.06.2023, 09:01
Попробуй алгоритм Дейкстры

Добавлено через 37 секунд
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
import heapq
 
 
class Solution:
    def shortest_path_binary_matrix(self, grid):
        n = len(grid)
        if grid[0][0] == 1 or grid[n-1][n-1] == 1:
            return -1
        
        # Создаем список смежности графа
        graph = [[] for _ in range(n*n)]
        for i in range(n):
            for j in range(n):
                if grid[i][j] == 0:
                    node = i*n+j
                    # Добавляем ребра для соседних ячеек
                    if i > 0 and grid[i-1][j] == 0:
                        graph[node].append((node-n, 1))
                    if j > 0 and grid[i][j-1] == 0:
                        graph[node].append((node-1, 1))
                    if i < n-1 and grid[i+1][j] == 0:
                        graph[node].append((node+n, 1))
                    if j < n-1 and grid[i][j+1] == 0:
                        graph[node].append((node+1, 1))
        
        # Запускаем алгоритм Дейкстры
        heap = [(0, 0)]  # Куча вершин для обработки
        dist = [float('inf')] * (n*n)  # Расстояние от начальной вершины до остальных
        dist[0] = 0
        
        while heap:
            d, node = heapq.heappop(heap)
            if node == n*n-1:
                return d
            if d > dist[node]:
                continue
            for neighbor, weight in graph[node]:
                new_dist = d + weight
                if new_dist < dist[neighbor]:
                    dist[neighbor] = new_dist
                    heapq.heappush(heap, (new_dist, neighbor))
        
        return -1
не уверен, что работает правильно, но все же))
1
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
23.06.2023, 09:53  [ТС]
Спасибо за ответ! Идея с алгоритмом Дейкстры, думаю, очень хорошая, но Ваш код на первом же тесте выдает -1, вместо 2. (Тесты есть выше). Попробую отредактировать его. Может, получится
0
Заблокирован
23.06.2023, 10:06
Цитата Сообщение от Doule_ Посмотреть сообщение
Решал задачу на литкоде
где ее там найти?
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38171 / 21106 / 4307
Регистрация: 12.02.2012
Сообщений: 34,701
Записей в блоге: 14
23.06.2023, 11:04
Цитата Сообщение от DOPIXKMNLD Посмотреть сообщение
Попробуй алгоритм Дейкстры
- Зачем? Обход в ширину!
0
32 / 24 / 11
Регистрация: 03.06.2023
Сообщений: 56
23.06.2023, 12:46  [ТС]
CoderPC, вот ссылка - https://leetcode.com/problems/... scription/
0
3750 / 1944 / 612
Регистрация: 21.11.2021
Сообщений: 3,706
24.06.2023, 04:09
Лучший ответ Сообщение было отмечено Doule_ как решение

Решение

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
from collections import deque
 
def BFS(matr):
    visited = set()
    inserted = {}
    n = len(matr)
    Ai, Aj = 0, 0
    Bi, Bj = n-1, n-1
    dec = deque()
    if matr[Ai][Aj] != 0:
        return -1
    dec.append((Ai, Aj))
    inserted[(Ai,Aj)] = 1
    while dec:
        i, j = dec.popleft()
        cur_dist = inserted[(i, j)]
        visited.add((i, j))
        if (i, j) == (Bi, Bj):
            return cur_dist
        for next_i, next_j in ((i+1,j+1), (i+1,j), (i,j+1), (i+1,j-1), (i-1,j+1), (i,j-1), (i-1,j), (i-1,j-1)):
            if not (next_i in range(n) and next_j in range(n)):
                continue
            if matr[next_i][next_j] == 0 and not (next_i, next_j) in visited:
                if not (next_i, next_j) in inserted:
                    inserted[(next_i, next_j)] = cur_dist + 1
                    dec.append((next_i, next_j))
    return -1
 
print(BFS([ [0, 0, 1, 1, 0, 0],
            [0, 0, 0, 0, 1, 1],
            [1, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, 0]]))
2
5516 / 2869 / 571
Регистрация: 07.11.2019
Сообщений: 4,759
24.06.2023, 08:15
Думаю, что можно и без графов решить, а использовать математическую морфологию. По сути нужно в верхнем левом углу установить в 1 стартовый пиксел (seed), в цикле делать дилатацию по окрестности 3x3 с маскированием, считать итерации и проверять нижний правый пиксель. Если правый нижний пиксель стал 1 или между итерациями ни один пиксель не закрасился, то останавливать цикл и выдавать или число итераций, или -1.
1
Заблокирован
30.06.2023, 06:49
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
class Solution:
    def shortestPathBinaryMatrix(self, grid)->int:
        n=len(grid)
        if grid[0][0]==0 and grid[n-1][n-1]==0:
            if n==1:
                return 1
            dx = [ -1, 0, 1, 1, 1, 0, -1, -1 ]
            dy = [ -1, -1, -1, 0, 1, 1, 1, 0 ]
            from collections import deque
            d=deque()
            d.append((0,0,1))
            while len(d)>0:
                s=d.popleft()
                for i in range(8):
                    x=s[0]+dx[i]
                    if x>=0 and x<n:
                        y=s[1]+dy[i]
                        ns=s[2]+1
                        if y>=0 and y<n and grid[y][x]==0:
                            if x==n-1 and y==n-1:
                                return ns
                            else:
                                grid[y][x]=1;
                                d.append((x,y,ns))
        return -1
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.06.2023, 06:49
Помогаю со студенческими работами здесь

Посчитать сумму диагонали матрицы с верхнего правого угла до нижнего левого
дана матрица посчитать сумму диагонали с верхнего правого угла до нижнего левого

Найти максимальный путь в матрице от левого верхнего угла до правого нижнего(ходить можно только вниз или вправо)
Нужно найти максимальный путь от левого верхнего угла до правого нижнего, ходить можно только вправо или влево, матрица заполняется...

Найти расстояние от верхнего левого угла до правого нижнего
срочно плиз!! нужно написать программу. суть задачи в следующем: задается произвольная прямоугольная матрица размером до 20(длина) и...

Движение объекта из левого нижнего угла до правого верхнего, и обратно
Сделал программу чтобы шарик двигался из левого нижнего угла до правого верхнего, но мне нужно чтобы он теперь пошел обратно. Как это...

Ассемблерные вставки - напечатать символы с левого верхнего угла и до правого нижнего
Требуется: 2 половины экрана. на одной половинке символы печатаются с левого верхнего угла и до правого нижнего, а на другой символы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru