[算法]LeetCode每日一题--990等式方程的可满足性(Java)

DailyChallenge

990. 等式方程的可满足性

Medium20200608

Description

给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:“a==b” 或 “a!=b”。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。

只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。

示例 1:

输入:["a==b","b!=a"]
输出:false
解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。

示例 2:

输出:["b==a","a==b"]
输入:true
解释:我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。

示例 3:

输入:["a==b","b==c","a==c"]
输出:true

示例 4:

输入:["a==b","b!=c","c==a"]
输出:false

示例 5:

输入:["c==c","b==d","x!=z"]
输出:true

提示:

  • 1 <= equations.length <= 500
  • equations[i].length == 4
  • equations[i][0] 和 equations[i][3] 是小写字母
  • equations[i][1] 要么是 ‘=’,要么是 ‘!’
  • equations[i][2] 是 ‘=’

Solution

  1. Floyd算法构建无向图,提供一个思路吧,虽然时间和空间复杂度都很大。
  2. 最近周赛,每日一题都是图相关的题目,所以我就往无向图的角度思考
  3. 先用一个26*26的数组存图
  4. 遍历equations建立相连的边
  5. 遍历equations中不等的来证伪
class Solution {
    public boolean equationsPossible(String[] equations) {
        int len = equations.length;
        // 只有一个等式的时候不会建图,所以特例分析
        // 注意["a!=a"]这个样例
        if(len == 1){
            if(equations[0].charAt(0) == equations[0].charAt(3) && equations[0].charAt(1) == '='){
                return true;
            }else if(equations[0].charAt(0) != equations[0].charAt(3) && equations[0].charAt(1) != '='){
                return true;
            }else{
                return false;
            }
        }
        // 先设为真,因为是通过==的等式建图,在通过!=的方式证伪
        boolean res = true;
        // 还是要建图
        // 都是小写字母,那就用数组的下标来代表字母
        // 因为这个可以都用数字来表示,所以用二维数组来比较方便
        // 否则像126题单词接龙II那样建图巨麻烦
        boolean[][] letters = new boolean [26][26];
        // 记录不等的式子的下标
        ArrayList<Integer> notEqualId = new ArrayList<>();
        for(int i = 0; i < len; i++){
            int m = equations[i].charAt(0) - 'a';
            int n = equations[i].charAt(3) - 'a';
            char sign = equations[i].charAt(1);
            if(sign == '='){
                // 无向图
                letters[m][n] = true;
                letters[n][m] = true;
            }else{
                notEqualId.add(i);
            }
        }
        // Floyd 算法建图
        // 这个算法很牛,一定要弄明白k为什么在最外层,可以查查博客
        // tips:Floyd算法是动态规划,这个k相当于状态转移相关的值
        for(int k = 0; k < 26; k++){
            for(int i = 0; i < 26; i++){
                for(int j = 0; j < 26; j++){
                    if(letters[i][k] && letters[k][j]){
                        letters[i][j] = true;
                    }
                }
            }
        }
        // 遍历不等的,如果不等的两个字母在图中已经相连,就可以返回false
        // 注意有equations[id].charAt(0)和equations[id].charAt(3)相等情况
        for(int i = 0; i < notEqualId.size(); i++){
            int id = notEqualId.get(i);
            int m = equations[id].charAt(0) - 'a';
            int n = equations[id].charAt(3) - 'a';
            // m和n相等的话,不会进判断,因为建图的时候就没有使得对角线相连了
            if(letters[m][n] || m == n){
                res = false;
            }
        }
        return res;

    }
}

  • 我的公众号: 每日分享LeetCode, 让你走在路上坐在车上也能看算法题,欢迎大家扫码关注。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值