Leetcode 399. 除法求值

在这里插入图片描述

心路历程:

一开始看着挺蒙的主要是不知道这道题在考察哪个知识点,后来按顺序把三个示例自己模拟着做出来之后发现本质其实在考类似链表或者指针的东西。
再一想其实是一个树或者图的遍历搜索问题,一下子想到了回溯算法。
第一次遇到这个题从读题到最后AC一共用了17分钟。当时犹豫了很久除法溢出的问题,后来想想就算有溢出问题也可以用path存储一个路径再去乘法。但是其实这道题给float留的裕度很大,直接用path /= number也可以直接AC。

做完之后看网上的答案基本上也是按照图+DFS的思路来做的

注意的点:

1、注意回溯函数nonlocal的声明,因为有些变量不是List Objective
2、注意每次初始化回溯的几大参数(path, res, visited, flag)
3、初始化visited = [start]而不是[],由于回溯函数的循环不变量编程原则。

解法: 建图(树)+DFS

class Solution:
    def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
        # 1. 建双向树 (其实是个图)
        element = {}
        for i in range(len(equations)):
            (x, y) = equations[i]
            if x not in element: element[x] = [(y, values[i])]
            else: element[x].append((y, values[i]))
            if y not in element: element[y] = [(x, 1.0 / values[i])]
            else: element[y].append((x, 1.0 / values[i]))
        # 2. 树的回溯函数
        def dfs(start, target):
            nonlocal path, visited, flag, res  # 2
            if start == target:
                flag = True
                res = path  # 3
                return
            candicate = element[start]
            for each in candicate:
                if each[0] not in visited:  # 这是一个能返回的树,所以必须用visited
                    visited.append(each[0])
                    path *= each[1]
                    dfs(each[0], target)
                    path /= each[1]  # ? 这道题没出现溢出问题
                    visited.pop()
        # 3. 回答问题
        ans = []
        for query in queries:
            (x, y) = query  # 解包
            if x not in element or y not in element: ans.append(-1)  # 根本没有这个元素
            else: # 注意初始化参数
                path, visited, flag, res = 1.0, [x], False, None  # 注意visited = [x] 循环不变量
                dfs(x, y)
                if flag: ans.append(res)
                else: ans.append(-1)
        return ans
  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值