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

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

22.06.2023, 18:59. Показов 1765. Ответов 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
38200 / 21132 / 4310
Регистрация: 12.02.2012
Сообщений: 34,738
Записей в блоге: 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
5517 / 2870 / 571
Регистрация: 07.11.2019
Сообщений: 4,761
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
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru