zoukankan      html  css  js  c++  java
  • 990.等式方程的可满足性

    image-20200608235933923

    提示

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

    题解1

    思路

    • 方程只有==!=两种情况,第一次遍历equations,当方程为==时,用长度为26(只有小写字母)的数组实时更新各字母的权值。
    • 第二次遍历 equations,判定方程为!=时,逻辑是否矛盾,矛盾有以下两种情形:
      • 等式左右两边字母相同
      • 等式左右两边权值都不为0且相同

    代码

     //直观方法  1ms
        public static boolean equationsPossible2(String[] equations) {
            int[] arr = new int[26];
            int count = 1;
            for (String str : equations) {
                if (str.charAt(1) == '=') {
                    int start = str.charAt(0) - 'a';
                    int end = str.charAt(3) - 'a';
                    if (arr[start] == 0 && arr[end] == 0) {
                        //都没出现过
                        arr[start] = arr[end] = count++;
                    } else if (arr[start] == 0 || arr[end] == 0) {
                        //只有一个出现个,则把权值设置一样
                        int max = Math.max(arr[start], arr[end]);
                        arr[start] = arr[end] = max;
                    } else {
                        //都出现过,两个集合相交, 把所有等于他俩值的权值设置同一个值。
                        int v1 = arr[start];
                        int v2 = arr[end];
                        for (int i = 0; i < arr.length; i++) {
                            if (arr[i] == v1 || arr[i] == v2) {
                                arr[i] = v1;
                            }
                        }
                    }
                }
            }
            for (String s : equations) {
                if (s.charAt(1) == '!') {
                    int start = s.charAt(0) - 'a';
                    int end = s.charAt(3) - 'a';
                    if (start == end) {//同一个字母
                        return false;
                    }
                    if (arr[start] != 0 && arr[end] != 0) {
                        if (arr[start] == arr[end]) {
                            return false;//矛盾
                        }
                    }
                }
            }
            return true;
        }
    

    并查集

    思路

    官方
    天使爆破组:手绘图解

    代码

    //1ms
    public boolean equationsPossible(String[] equations) {
            int len = equations.length;
            int[] parent = new int[26];
            for (int i = 0; i < 26; i++) {
                parent[i] = i;
            }
            for (String str : equations) {
                if (str.charAt(1) == '=') {
                    int index1 = str.charAt(0) - 'a';
                    int index2 = str.charAt(3) - 'a';
                    union(parent, index1, index2);
                }
            }
    
            for (String str : equations) {
                if (str.charAt(1) == '!') {
                    int index1 = str.charAt(0) - 'a';
                    int index2 = str.charAt(3) - 'a';
                    if (find(parent, index1) == find(parent, index2)) {
                        return false;
                    }
                }
            }
            return true;
        }
    
        private void union(int[] parent, int index1, int index2) {
            parent[find(parent, index1)] = find(parent, index2);
        }
    
        private int find(int[] parent, int index) {
            while (parent[index] != index) {
                parent[index] = parent[parent[index]];
                index = parent[index];
            }
            return index;
        }
    }
    

    参考链接

    官方题解

    @Alexand_ER题解

  • 相关阅读:
    大厂面试高频Redis,记不住的多操作几次吧
    自动化测试系列之jenkins配置搭建环境
    关于linux服务器的磁盘监控的相关知识
    前端常见一些安全问题及解决方案
    如何使用PM2部署前端项目
    vuex状态管理器本地持久化
    关于在Vue中Typescript的写法
    websocket快速重连机制
    如何使用selenium打开多个浏览器
    运维人员踩坑记录之netplan遇坑,配置临时IP巧妙解决
  • 原文地址:https://www.cnblogs.com/yh-simon/p/13069860.html
Copyright © 2011-2022 走看看