leetcode6-08每日一题:等式方程的可满足性

前两天困难难度的题把我都做到自闭了,导致最后根本就不想写题解(也写不出来)。今天终于见到了一个看起来还能做的题,心里突然感觉有了希望,于是乎在尝试三种不同思路、大改代码几次后终于做出来了……
先上题目:
题目
最开始我想到的办法就是分块记录等式和不等式,把相等的放在一个组,不等的分开放在不同的组,但是越写越觉得不对劲,因为这样根本没法进行判断,在逻辑上就行不通。于是乎半个小时过去了。
然后我又想了一个办法,就是先对所有式子进行排序,等式在前先处理,不等式后处理。然后把等式的字母放在一个集合中,不等式的字母先拿到等式字母的集合中来看看在不在,在的话返回False,不在的话放在另一个集合中。这种方法看起来似乎行得通,但是现实又给了我一个暴击,因为很容易就能找到反例。
现在以其中两个测试用例来进行说明:
反例
这种方法不行,那应该怎么解决呢?我想了想,这种方法的问题主要出在把所有等式字母混在一起了,如果能把这些字母按照等式连接的情况分好组,那不就可以解决了嘛?而且回看处理过程,其实不等式的字母可以不加入到集合中。
因此我认为可以在上述方法的基础上进行以下修改:

①把等式和不等式分离,先处理等式构造可以连接的set list,再处理不等式
②等式形成的set list需要进行合并处理,最后输出一个组内元素两两不相交的set list
③对不等式的两端元素放到set list中进行判定,如果在同一个set中则直接返回False,否则跳过

以一个例子来说明为什么需要合并:
在这里插入图片描述
有了思路后,代码就很简单啦!代码如下所示:

class Solution:
    def equationsPossible(self, equations: List[str]) -> bool:
        #以下两个列表分别记录等式和不等式
        equal = []
        unequal = []
        for i in range(len(equations)):
            if equations[i][1] == "=":
                equal.append(equations[i])
            else:
                unequal.append(equations[i])
        record = []
        #首先把等式所有可能的情况加进去集合中
        for i in range(len(equal)):
            signal = 0
            for j in range(len(record)):
                if equal[i][0] in record[j] or equal[i][3] in record[j]:
                    record[j].add(equal[i][0])
                    record[j].add(equal[i][3])
                    signal = 1
                    break
            if signal == 0:
                record.append(set([equal[i][0], equal[i][3]]))
        #进行减少集合数量的操作,把并集不为空的集合合并,使得最后输出的集合钟的元素两两不相交
        while True:
            signal = 0
            for i in range(len(record)-1):
                for j in range(i + 1, len(record)):
                    #如果相交,就改前面那个集合,然后删掉后面的那个集合,跳出来重新循环(因为记录集合的列表长度变了)
                    if not set.isdisjoint(record[i], record[j]):
                        record[i] = set.union(record[i], record[j])
                        record.remove(record[j])
                        signal  = 1
                        break
                if signal == 1:
                    break
            #如果记录集合的列表没有修改过,说明列表内的集合两两不相交,跳出循环
            if signal == 0:
                break
        #对不等式进行判断
        for i in range(len(unequal)):
            #如果有两边相等的,直接False
            if unequal[i][0] == unequal[i][3]:
                return False
            #看两边的元素是否在同一个集合中,在就返回False
            for j in range(len(record)):
                if unequal[i][0] in record[j] and unequal[i][3] in record[j]:
                    return False
        return True

终于,在被困难题目虐了两天之后,我在早上就解好了题,实在是太感动了,虽然效率不咋地😭
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值