leetcode990-等式方程的可满足性

原题

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

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

示例 1:

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

示例 2:

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

示例 3:

输入: ["ab","bc","ac"] 输出: true

示例 4:

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

示例 5:

输入: ["cc","bd","x!=z"] 输出: true

提示:

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

解法

本题解同步发于leetcode题解:简洁的Java并查集

思想

见代码部分

代码

我写的这个代码没有任何优化但是很简洁,使用的HashMap实现的并查集(如果不了解并查集建议先去学习一下哦,还是蛮实用的一个数据结构的)

比较重要的思路是一定要先将字符串方程按相等到不等来排序,相等的方程用于建立并查集,不等的方程用于判断是否出错(即不等的两个代数是否出现在了同一个集合中)。

class Solution {
    public boolean equationsPossible(String[] equations) {
        // 并查集
        Map<Character,Character> father = new HashMap<>();
        // 先将字符串方程从相等到不等排序
        Arrays.sort(equations,(s1,s2)->{
            if(s1.charAt(1)==s2.charAt(1)) return 0;
            return s1.charAt(1)=='='?-1:1;
        });

        for(String s:equations){
            char[] chars = s.toCharArray();
            char first = chars[0];
            char second = chars[3];
            // 获取根代表
            while(father.containsKey(first) ) first = father.get(first);
            while(father.containsKey(second)) second = father.get(second);
            // 如果是不等,但根代表相同,说明出错
            if(chars[1] == '!'){
                if(first == second) return false;
            // 如果是相等,跳过根代表相同的情况,把一个根代表连接到另一个根代表上(合并集合)
            }else{
                if(first == second) continue;
                father.put(first, second);
            }
        }
        return true;
    }
}

刚看了下官方的题解并没有先排序,而是进行了两次遍历,第一次处理相等的,第二次处理不等的,确实比我写的时间复杂度要好,那么按这个思路修改之后就是:

class Solution {
    public boolean equationsPossible(String[] equations) {
        Map<Character,Character> father = new HashMap<>();
        //建立并查集
        for(String s:equations){
            char[] chars = s.toCharArray();
            if(chars[1] == '='){
                char first = chars[0];
                char second = chars[3];
                while(father.containsKey(first) ) first = father.get(first);
                while(father.containsKey(second)) second = father.get(second);
                if(first == second) continue;
                father.put(first, second);
            }
        }
        //检查是否有错
        for(String s:equations){
            char[] chars = s.toCharArray();
            if(chars[1] == '!'){
                char first = chars[0];
                char second = chars[3];
                while(father.containsKey(first) ) first = father.get(first);
                while(father.containsKey(second)) second = father.get(second);
                if(first == second) return false;
            }
        }
        return true;
    }
}

可以发现有一些重复代码,如果抽取成一个函数会更简洁,还有哈希集可以写成数组,时间成本会更低一些,感兴趣的小伙伴自己试试优化啦(^_^)。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode990-%e7%ad%89%e5%bc%8f%e6%96%b9%e7%a8%8b%e7%9a%84%e5%8f%af%e6%bb%a1%e8%b6%b3%e6%80%a7/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年6月7日
下一篇 2020年6月9日

相关推荐

  • leetcode841-钥匙和房间

    原题 有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。 在形式上,对于每个房间 i 都有一…

    2019年12月13日
    0130
  • leetcode155-最小栈

    原题 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) – 将元素 x 推入栈中。 pop() – 删除栈顶的元素。 top() …

    算法 2019年12月11日
    0130
  • leetcode15-三数之和

    原题 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意:…

    算法 2020年5月4日
    0190
  • leetcode2-两数相加

    原题 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回…

    算法 2019年12月17日
    080
  • leetcode189-旋转数组

    原题 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 示例1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4…

    算法 2019年11月22日
    050
  • 剑指offer59-队列的最大值

    原题(来源Leetcode) 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的时间复杂度…

    算法 2020年3月7日
    0130
  • leetcode347-前K个高频元素

    原题 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 示例1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例2: 输入: n…

    算法 2019年12月28日
    0170
  • leetcode509-斐波那契数

    原题 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,   F(1) …

    算法 2020年1月21日
    0120
  • leetcode341-扁平化嵌套列表迭代器

    原题 给定一个嵌套的整型列表。设计一个迭代器,使其能够遍历这个整型列表中的所有整数。 列表中的项或者为一个整数,或者是另一个列表。 示例1: 输入: [[1,1],2,[1,1]]…

    算法 2020年1月27日
    050
  • leetcode26-删除排序数组中的重复项

    原题 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空…

    算法 2019年11月23日
    0210

发表回复

登录后才能评论