东莞公司网站制作要多少钱,免费设计app的网站建设,小学生手工制作,怎么让网站让百度收录1 题目
2260. 必须拿起的最小连续卡牌数
给你一个整数数组 cards #xff0c;其中 cards[i] 表示第 i 张卡牌的 值 。如果两张卡牌的值相同#xff0c;则认为这一对卡牌 匹配 。
返回你必须拿起的最小连续卡牌数#xff0c;以使在拿起的卡牌中有一对匹配的卡牌。如果无法…1 题目2260. 必须拿起的最小连续卡牌数给你一个整数数组cards其中cards[i]表示第i张卡牌的值。如果两张卡牌的值相同则认为这一对卡牌匹配。返回你必须拿起的最小连续卡牌数以使在拿起的卡牌中有一对匹配的卡牌。如果无法得到一对匹配的卡牌返回-1。示例 1输入cards [3,4,2,3,4,7]输出4解释拿起卡牌 [3,4,2,3] 将会包含一对值为 3 的匹配卡牌。注意拿起 [4,2,3,4] 也是最优方案。示例 2输入cards [1,0,5,3]输出-1解释无法找出含一对匹配卡牌的一组连续卡牌。提示1 cards.length 1050 cards[i] 1062 代码实现class Solution { public: int minimumCardPickup(vectorint cards) { unordered_mapint,int last_occurrence ; int min_length INT_MAX ; for(int idx 0 ; idx cards.size() ;idx){ int num cards[idx]; if(last_occurrence.count(num)){ int current_length idx - last_occurrence[num] 1 ; min_length min(min_length , current_length); } last_occurrence[num] idx ; } return min_length INT_MAX ? -1 : min_length; } };这怎么做双指针但是我还要找一下最小的两个双指针的距离滑动窗口那我也不知道窗口长度解题思路你提到了双指针和滑动窗口其实这道题用哈希表字典记录元素最后出现的位置的方法会更高效时间复杂度是 O (n)n 为数组长度比双指针 / 滑动窗口更适合处理这道题的大数据量数组长度可达 10^5。采用哈希表unordered_map记录元素最后出现的下标的方法这是处理该问题最高效的方式时间复杂度为 O (n)n 为数组长度能很好应对题目中 10^5 的数组长度限制。具体步骤和之前一致用哈希表存储每个卡牌值最后一次出现的下标。遍历数组对每个元素若已在哈希表中计算当前下标与上次下标差 1即连续卡牌数并更新最小值若不在则存入哈希表。遍历结束后根据最小值是否更新返回结果。代码实现#include vector #include unordered_map #include climits // 包含INT_MAX的定义 using namespace std; int minimumCardPickup(vectorint cards) { // 哈希表键为卡牌值值为该值最后一次出现的下标 unordered_mapint, int last_occurrence; // 初始化最小长度为整型最大值 int min_length INT_MAX; for (int idx 0; idx cards.size(); idx) { int num cards[idx]; // 如果当前卡牌值已经出现过 if (last_occurrence.find(num) ! last_occurrence.end()) { // 计算当前连续卡牌数当前下标 - 上一次出现的下标 1 int current_length idx - last_occurrence[num] 1; // 更新最小长度 min_length min(min_length, current_length); } // 无论是否出现过都更新为当前下标保留最近的位置 last_occurrence[num] idx; } // 如果最小长度还是INT_MAX说明没有匹配的卡牌返回-1否则返回最小长度 return min_length INT_MAX ? -1 : min_length; } // 测试代码可选用于验证功能 #include iostream int main() { vectorint cards1 {3,4,2,3,4,7}; cout minimumCardPickup(cards1) endl; // 输出4 vectorint cards2 {1,0,5,3}; cout minimumCardPickup(cards2) endl; // 输出-1 return 0; }代码解释头文件引入vector用于存储数组unordered_map作为哈希表climits提供整型最大值INT_MAXiostream用于测试时的输入输出。哈希表与最小长度初始化last_occurrence记录卡牌值的最新下标min_length初始化为INT_MAX表示初始时无匹配。遍历数组遍历每个元素时用find方法检查该值是否在哈希表中若存在计算连续卡牌数并更新最小值若不存在直接存入。每次遍历都更新哈希表中该值的下标为当前下标保证后续能计算更短的连续长度。结果返回判断min_length是否仍为INT_MAX是则返回 - 1否则返回最小值。测试代码通过两个示例数组验证函数功能输出对应结果。核心代码实现LeetCode 的题目通常会给出函数的定义框架我们只需要填充核心逻辑即可以下是可以直接提交的代码#include vector #include unordered_map #include climits using namespace std; class Solution { public: int minimumCardPickup(vectorint cards) { // 哈希表存储卡牌值对应的最后出现的下标 unordered_mapint, int last_occurrence; // 初始化最小长度为整型最大值 int min_length INT_MAX; for (int idx 0; idx cards.size(); idx) { int num cards[idx]; // 如果当前卡牌值已经出现过计算连续卡牌数并更新最小值 if (last_occurrence.count(num)) { int current_length idx - last_occurrence[num] 1; min_length min(min_length, current_length); } // 更新当前卡牌值的最新下标 last_occurrence[num] idx; } // 无匹配则返回-1否则返回最小长度 return min_length INT_MAX ? -1 : min_length; } };代码优化说明这里我将原代码中的last_occurrence.find(num) ! last_occurrence.end()替换为了last_occurrence.count(num)两者功能等价都是判断键是否存在但count方法在 C 中写起来更简洁也是 LeetCode 中常用的写法。总结LeetCode 提交的核心代码需要包裹在Solution类中且函数名和参数要与题目给出的一致。核心逻辑依然是用哈希表记录元素最新下标遍历过程中计算最小连续卡牌数时间复杂度为 O (n)。代码中仅保留必要的头文件和核心逻辑去除测试代码符合 LeetCode 的提交规范。C 实现中使用unordered_map作为哈希表其查找和插入操作的平均时间复杂度为 O (1)保证整体算法效率为 O (n)。核心逻辑是记录元素最新下标并实时计算最小连续长度这是解决该问题的关键。注意使用INT_MAX作为初始值时需要引入climits头文件避免编译错误。3 题目2001. 可互换矩形的组数用一个下标从0开始的二维整数数组rectangles来表示n个矩形其中rectangles[i] [widthi, heighti]表示第i个矩形的宽度和高度。如果两个矩形i和ji j的宽高比相同则认为这两个矩形可互换。更规范的说法是两个矩形满足widthi/heighti widthj/heightj使用实数除法而非整数除法则认为这两个矩形可互换。计算并返回rectangles中有多少对可互换矩形。示例 1输入rectangles [[4,8],[3,6],[10,20],[15,30]]输出6解释下面按下标从 0 开始列出可互换矩形的配对情况 - 矩形 0 和矩形 1 4/8 3/6 - 矩形 0 和矩形 2 4/8 10/20 - 矩形 0 和矩形 3 4/8 15/30 - 矩形 1 和矩形 2 3/6 10/20 - 矩形 1 和矩形 3 3/6 15/30 - 矩形 2 和矩形 3 10/20 15/30示例 2输入rectangles [[4,5],[7,8]]输出0解释不存在成对的可互换矩形。提示n rectangles.length1 n 105rectangles[i].length 21 widthi, heighti 1054 代码实现class Solution { private: struct PairHash{ template typename T1 , typename T2 size_t operator()(const pairT1, T2 p )const { auto h1 hash T1()(p.first); auto h2 hash T2()(p.second); return h1 ^ (h2 1); } }; public: long long interchangeableRectangles(vectorvectorint rectangles) { unordered_map pairint ,int ,int ,PairHash ratio_count ; long long result 0 ; for (auto rect : rectangles){ int w rect[0]; int h rect[1]; int g gcd(w,h); int num w / g ; int den h / g ; ratio_count[{num ,den}] ; } for (auto entry :ratio_count){ long long k entry.second; result k * (k - 1) / 2 ; } return result; } };我觉得实数除法是不是就是强制类型转化一下double然后严格比较另外做一个计数count你现在需要解决的是 “可互换矩形的组数” 问题核心需求是统计数组中宽高比相同的矩形配对数量其中配对要求 i j。你提到用 double 存储宽高比并比较这个思路有问题浮点数精度误差会导致错误正确的做法是将宽高比化简为最简分数用分子和分母的最大公约数约分再用哈希表统计相同最简分数的矩形数量最后计算组合数。解题思路问题分析如果直接用double存储宽高比比如 4/80.53/60.5看似可行但对于大数如 100000/99999浮点数的精度限制会导致两个实际相等的比值被判定为不相等从而出错。因此需要用最简分数来唯一表示宽高比。化简分数对于每个矩形的宽w和高h计算它们的最大公约数gcd(w, h)然后将w/gcd和h/gcd作为最简分数的分子和分母为了统一表示还可以约定分子分母的顺序比如让分子分母的最大公约数为正或让分子大于分母这里直接约分即可。统计数量用哈希表存储每个最简分数对应的矩形数量键可以是 pairint, int或用字符串拼接、自定义哈希的方式存储分子分母。计算组合数对于每个数量为k的最简分数能组成的配对数是组合数C(k, 2) k*(k-1)/2从 k 个中选 2 个的组合数将所有组合数相加即为答案。代码实现#include vector #include unordered_map #include numeric // 包含gcd函数C17及以上 using namespace std; // 为了让unordered_map支持pairint, int作为键需要自定义哈希函数 struct PairHash { template typename T1, typename T2 size_t operator()(const pairT1, T2 p) const { auto h1 hashT1()(p.first); auto h2 hashT2()(p.second); // 组合两个哈希值避免冲突 return h1 ^ (h2 1); } }; class Solution { public: long long interchangeableRectangles(vectorvectorint rectangles) { // 哈希表键为(最简分子, 最简分母)值为该比例的矩形数量 unordered_mappairint, int, int, PairHash ratio_count; long long result 0; // 结果可能很大用long long存储 for (auto rect : rectangles) { int w rect[0]; int h rect[1]; // 计算w和h的最大公约数注意gcd的参数是非负整数这里题目中w和h都是正整数 int g gcd(w, h); // 化简为最简分数 int num w / g; int den h / g; // 统计该比例的数量 ratio_count[{num, den}]; } // 遍历哈希表计算每个比例的组合数 for (auto entry : ratio_count) { long long k entry.second; // 组合数C(k,2) k*(k-1)/2 result k * (k - 1) / 2; } return result; } };代码解释自定义哈希函数C 的unordered_map默认不支持pairint, int作为键因此需要自定义PairHash结构体将两个整数的哈希值组合起来作为键的哈希值。化简分数使用numeric头文件中的gcd函数C17 及以上支持计算宽和高的最大公约数然后将宽和高分别除以最大公约数得到最简分数的分子和分母。统计数量遍历每个矩形将化简后的分子分母作为键在哈希表中统计对应数量。计算组合数对于每个比例的数量k计算k*(k-1)/2并累加到结果中注意用long long存储避免整数溢出因为 n 可达 10^5k 最大为 10^5k*(k-1) 会超过 int 的范围。补充说明关于浮点数的问题如果用double存储宽高比比如测试用例中的[100000, 99999]和[200000, 199998]它们的实际比值是相等的但由于浮点数的精度限制100000.0/99999.0和200000.0/199998.0可能会被存储为不同的二进制数导致比较结果为不相等从而统计错误。因此绝对不能用浮点数来表示宽高比。测试用例验证示例 1rectangles [[4,8],[3,6],[10,20],[15,30]]化简后都是(1,2)数量k4组合数4*3/26结果为 6。示例 2rectangles [[4,5],[7,8]]化简后分别是(4,5)和(7,8)数量都是 1组合数为 0结果为 0。总结核心避坑点不要用浮点数存储宽高比必须用最简分数来唯一标识比例避免精度误差。关键步骤计算宽高的最大公约数化简分数 → 哈希表统计比例数量 → 计算组合数C(k,2)累加。数据类型结果和数量k要用long long防止整数溢出。浮点数精度误差会导致错误没懂就算是2/ 4 和1/2的存储会不一样你之所以没懂浮点数精度误差的问题是因为2/4 和 1/2 这种简单的分数用浮点数存储确实是一样的但问题出在复杂的分数或大数的分数上。浮点数的存储机制是二进制近似表示不是精确存储这会导致一些看似相等的分数在转换成浮点数后出现微小的差异。核心需求回顾你想理解为什么浮点数精度误差会导致可互换矩形的判断错误我们从浮点数的存储原理和实际例子入手就能彻底搞懂。先搞懂浮点数double/float是怎么存储的计算机中的浮点数比如 C 的double遵循IEEE 754 标准用符号位 指数位 尾数位的二进制形式存储尾数位的长度是有限的double的尾数位有 52 位。这意味着只有少数十进制小数比如 0.5、0.25、0.125 等能表示为 2 的负次幂可以被精确存储。大多数十进制小数比如 0.1、0.3、100000/99999 等只能被近似存储存储的是一个接近真实值的二进制数。举两个例子直观看到精度误差例子 1简单分数没问题2/4 0.51/2 0.50.5 的二进制是0.1可以被double精确存储所以这两个浮点数是相等的。例子 2复杂分数出问题了我们看两个数学上相等的分数但转换成double后却不相等#include iostream #include iomanip // 用于输出高精度浮点数 using namespace std; int main() { // 分数1100000 / 99999 double ratio1 100000.0 / 99999.0; // 分数2200000 / 199998化简后和分数1相等都是100000/99999 double ratio2 200000.0 / 199998.0; // 输出高精度的浮点数 cout fixed setprecision(20); cout ratio1 ratio1 endl; cout ratio2 ratio2 endl; cout ratio1 ratio2 ? (ratio1 ratio2 ? Yes : No) endl; return 0; }运行结果关键看差异ratio1 1.00001000010000100000 ratio2 1.00001000010000090000 // 注意最后几位和ratio1不一样 ratio1 ratio2 ? No你看这两个数学上完全相等的分数转换成double后因为尾数位的限制存储的近似值出现了微小差异导致判断为false。例子 3更常见的 0.1 问题经典精度误差#include iostream #include iomanip using namespace std; int main() { double a 0.1; double b 0.1 0.1 0.1; double c 0.3; cout fixed setprecision(20); cout b b endl; // 0.30000000000000004441 cout c c endl; // 0.29999999999999998890 cout b c ? (b c ? Yes : No) endl; // No return 0; }这也是同样的道理0.1 无法被二进制精确存储累加后误差被放大导致0.10.10.1 ! 0.3。回到题目为什么这会导致统计错误在题目中矩形的宽和高可以达到10^5很容易出现类似100000/99999这样的分数。如果用double存储宽高比就会出现两个数学上可互换的矩形因为浮点数精度误差被判定为不可互换。最终统计的配对数会比实际少导致答案错误。而用最简分数表示宽高比时是精确存储的比如(100000, 99999)和(100000, 99999)绝对相等不会出现这种问题。总结浮点数的精度误差根源double的尾数位有限只能精确存储少数十进制小数大多数分数会被近似存储。题目中的风险大数的分数如 1e5 级别的宽高比极易出现近似值差异导致可互换矩形的判断错误。解决方案用最简分数分子 分母精确表示宽高比避免浮点数的精度问题。简单来说2/4 和 1/2 没问题但复杂分数会出问题而题目中的数据范围会让这种问题必然发生所以必须用最简分数的方式。