No.990 LeetCode題目 “等式方程的可滿足性”

題目描述

給定一個由表示變量之間關係的字符串方程組成的數組,每個字符串方程 equations[i] 的長度爲4,並採用兩種不同的形式之一:"a==b""a!=b"。在這裏,ab 是小寫字母(不一定不同),表示單字母變量名。

只有當可以將整數分配給變量名,以便滿足所有給定的方程時才返回 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]'='

解題思路

本題採用並查集的思想:(不太瞭解並查集的小夥伴可看【算法基礎】並查集的原理及使用

  • 第一遍循環,將equations[i] 中等式都找出來,然後將等式左右兩邊的字母放入同一集合;
  • 第二遍循環,判斷equations[i] 中若有不等式兩邊字母屬於同一集合,則返回false,否則返回true

本題利用數組的方式存儲每個單詞的父親節點。
find()函數返回該字母的根結點。

若等式兩邊的數字相等,則讓左邊數字的根結點的父親節點指向右邊數字的根結點。

find()函數函數中:

  • return find(parent[index]); 此方法爲不壓縮路徑的方法
  • parent[index] = find(parent[index]);
    return parent[index];此方法爲壓縮路徑的方法

壓縮路徑的方法在查找時較快,運行所需時間較少。

具體代碼

class Solution {
public:

    //定義一個長度爲26的數組parent,用於存放父節點
    int parent[26];
    
    //查找根結點
    int find(int index){
      //根結點是自身
      if(index == parent[index]) return index;
      //如果不是的話則一直向上尋找根結點,同時壓縮路徑
      parent[index] = find(parent[index]);
      return parent[index];
      //return find(parent[index]);  此方法爲不壓縮路徑的方法
    }
    
    //合併函數,將第一個數的根結點的父節點指向第二個數的根結點
    void unite(int index1, int index2){
      parent[find(index1)] = find(index2);
    }

    bool equationsPossible(vector<string>& equations) {
      //開始時自己指向自己
      for(int i = 0;i<26;i++) parent[i] = i;
           
      //先循環一邊,將相同的添加到同一集合中
      for(int i = 0;i<equations.size();i++){
        if(equations[i][1] == '='){
          int index1 = equations[i][0] - 'a';
          int index2 = equations[i][3] - 'a';
          unite(index1, index2);
        }
      }
      //開始查找並判斷是否在同一集合
      for(int i = 0;i<equations.size();i++){
        if(equations[i][1] == '!'){
          int index1 = equations[i][0] - 'a';
          int index2 = equations[i][3] - 'a';
          if(find(index1) == find(index2)) return false;
        }
      }
      for(int i = 0; i<6;i++)cout<<parent[i]<<"  ";
      return true;
    }
};

性能結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章