LeetCode - 1128. 等价多米诺骨牌对的数量

2024-05-11 17:38

本文主要是介绍LeetCode - 1128. 等价多米诺骨牌对的数量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述

给你一个由一些多米诺骨牌组成的列表 dominoes。

如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。

形式上,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 a==c 且 b==d,或是 a==d 且 b==c。

在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。

 

示例:

输入:dominoes = [[1,2],[2,1],[3,4],[5,6]]
输出:1
 

提示:

1 <= dominoes.length <= 40000
1 <= dominoes[i][j] <= 9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-equivalent-domino-pairs/
 

求解

    class Solution {public:// 方法一, 暴力解法// 超时未通过int numEquivDominoPairs_vio(vector<vector<int>> &dominoes) {const int n = dominoes.size();int count = 0;for (int i = 0; i < n - 1; ++i) {for (int j = i + 1; j < n; ++j) {if (isDominoes(dominoes[i], dominoes[j])) {++count;}}}return count;}// 方法二,利用查找表// 低效率通过int numEquivDominoPairs_2e(const vector<vector<int>> &dominoes) {const int n = dominoes.size();int count = 0;std::unordered_map<int, vector<vector<int>>> record; // <和, 点对数组>记录,用于快速查找for (auto &dominoe : dominoes) {int sum = dominoe[0] + dominoe[1];if (record.count(sum) > 0) {const auto &vecs = record[sum];for (const auto &vec : vecs) {if (isDominoes(dominoe, vec)) {++count;}}}record[sum].push_back(std::move(dominoe));}return count;}// 方法三,参考官方解答// 1 <= dominoes[i][j] <= 9,因此对每对的两个数字编码,10*min(x,y) + max(x,y)肯定总是小于100int numEquivDominoPairs_3e(const vector<vector<int>> &dominoes) {vector<int> record(100, 0); // 100做记录足够了int res = 0;for (const auto &p : dominoes) {int val = p[0] < p[1] ? 10 * p[0] + p[1] : 10 * p[1] + p[0];res += record[val];++record[val];}return res;}// 方法四,hash散列,重定义等价性计数,就是速度太慢// 函数对象实现hash计算struct dominoeHash {std::size_t operator()(const vector<int> &vec) const {std::hash<int> intHash;return vec[0] < vec[1] ? intHash(vec[0]) ^ intHash(vec[1]) : intHash(vec[1]) ^ intHash(vec[0]);}};// 函数对象实现equal_tostruct dominoeEqualTo {bool operator()(const vector<int> &vec1, const vector<int> &vec2) const {return (vec1[0] == vec2[0] && vec1[1] == vec2[1]) || (vec1[0] == vec2[1] && vec1[1] == vec2[0]);}};int numEquivDominoPairs(const vector<vector<int>> &dominoes) {// todo 使用lambda表达式
//            auto const &hashcode = [](const vector<int> &vec) {
//                std::hash<int> intHash;
//                return vec[0] < vec[1] ? intHash(vec[0]) ^ intHash(vec[1]) : intHash(vec[1]) ^ intHash(vec[0]);
//            };
//
//            auto const &equalDominoe = [](const vector<int> &vec1, const vector<int> &vec2) {
//                return (vec1[0] == vec2[0] && vec1[1] == vec2[1]) || (vec1[0] == vec2[1] && vec1[1] == vec2[0]);
//            };// 使用函数对象实现hash计算和equal_toint count = 0;std::unordered_multiset<vector<int>, dominoeHash, dominoeEqualTo> record;for (const auto &p : dominoes) {int num = record.count(p);if (num > 0) {count += num;}record.emplace(p.begin(), p.end());}return count;}private:inline bool isDominoes(const vector<int> &vec1, const vector<int> &vec2) const {return (vec1[0] == vec2[0] && vec1[1] == vec2[1]) || (vec1[0] == vec2[1] && vec1[1] == vec2[0]);}};

 

这篇关于LeetCode - 1128. 等价多米诺骨牌对的数量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/980213

相关文章

MySQL精准控制Binlog日志数量的三种方案

《MySQL精准控制Binlog日志数量的三种方案》作为数据库管理员,你是否经常为服务器磁盘爆满而抓狂?Binlog就像数据库的“黑匣子”,默默记录着每一次数据变动,但若放任不管,几天内这些日志文件就... 目录 一招修改配置文件:永久生效的控制术1.定位my.cnf文件2.添加核心参数不重启热更新:高手应

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划