|
| 1 | +--- |
| 2 | +title: 3606.优惠券校验器:分类 + 排序 |
| 3 | +date: 2025-12-13 22:44:25 |
| 4 | +tags: [题解, LeetCode, 简单, 数组, 字符串, 排序] |
| 5 | +categories: [题解, LeetCode] |
| 6 | +--- |
| 7 | + |
| 8 | +# 【LetMeFly】3606.优惠券校验器:分类 + 排序 |
| 9 | + |
| 10 | +力扣题目链接:[https://leetcode.cn/problems/coupon-code-validator/](https://leetcode.cn/problems/coupon-code-validator/) |
| 11 | + |
| 12 | +<p>给你三个长度为 <code>n</code> 的数组,分别描述 <code>n</code> 个优惠券的属性:<code>code</code>、<code>businessLine</code> 和 <code>isActive</code>。其中,第 <code>i</code> 个优惠券具有以下属性:</p> |
| 13 | + |
| 14 | +<ul> |
| 15 | + <li><code>code[i]</code>:一个 <strong>字符串</strong>,表示优惠券的标识符。</li> |
| 16 | + <li><code>businessLine[i]</code>:一个 <strong>字符串</strong>,表示优惠券所属的业务类别。</li> |
| 17 | + <li><code>isActive[i]</code>:一个 <strong>布尔值</strong>,表示优惠券是否当前有效。</li> |
| 18 | +</ul> |
| 19 | + |
| 20 | +<p>当以下所有条件都满足时,优惠券被认为是 <strong>有效的 </strong>:</p> |
| 21 | + |
| 22 | +<ol> |
| 23 | + <li><code>code[i]</code> 不能为空,并且仅由字母数字字符(a-z、A-Z、0-9)和下划线(<code>_</code>)组成。</li> |
| 24 | + <li><code>businessLine[i]</code> 必须是以下四个类别之一:<code>"electronics"</code>、<code>"grocery"</code>、<code>"pharmacy"</code>、<code>"restaurant"</code>。</li> |
| 25 | + <li><code>isActive[i]</code> 为 <strong>true </strong>。</li> |
| 26 | +</ol> |
| 27 | + |
| 28 | +<p>返回所有 <strong>有效优惠券的标识符 </strong>组成的数组,按照以下规则排序:</p> |
| 29 | + |
| 30 | +<ul> |
| 31 | + <li>先按照其 <strong>businessLine</strong> 的顺序排序:<code>"electronics"</code>、<code>"grocery"</code>、<code>"pharmacy"</code>、<code>"restaurant"</code>。</li> |
| 32 | + <li>在每个类别内,再按照 <strong>标识符的字典序(升序)</strong>排序。</li> |
| 33 | +</ul> |
| 34 | + |
| 35 | +<p> </p> |
| 36 | + |
| 37 | +<p><strong class="example">示例 1:</strong></p> |
| 38 | + |
| 39 | +<div class="example-block"> |
| 40 | +<p><strong>输入:</strong> <span class="example-io">code = ["SAVE20","","PHARMA5","SAVE@20"], businessLine = ["restaurant","grocery","pharmacy","restaurant"], isActive = [true,true,true,true]</span></p> |
| 41 | + |
| 42 | +<p><strong>输出:</strong> <span class="example-io">["PHARMA5","SAVE20"]</span></p> |
| 43 | + |
| 44 | +<p><strong>解释:</strong></p> |
| 45 | + |
| 46 | +<ul> |
| 47 | + <li>第一个优惠券有效。</li> |
| 48 | + <li>第二个优惠券的标识符为空(无效)。</li> |
| 49 | + <li>第三个优惠券有效。</li> |
| 50 | + <li>第四个优惠券的标识符包含特殊字符 <code>@</code>(无效)。</li> |
| 51 | +</ul> |
| 52 | +</div> |
| 53 | + |
| 54 | +<p><strong class="example">示例 2:</strong></p> |
| 55 | + |
| 56 | +<div class="example-block"> |
| 57 | +<p><strong>输入:</strong> <span class="example-io">code = ["GROCERY15","ELECTRONICS_50","DISCOUNT10"], businessLine = ["grocery","electronics","invalid"], isActive = [false,true,true]</span></p> |
| 58 | + |
| 59 | +<p><strong>输出:</strong> <span class="example-io">["ELECTRONICS_50"]</span></p> |
| 60 | + |
| 61 | +<p><strong>解释:</strong></p> |
| 62 | + |
| 63 | +<ul> |
| 64 | + <li>第一个优惠券无效,因为它未激活。</li> |
| 65 | + <li>第二个优惠券有效。</li> |
| 66 | + <li>第三个优惠券无效,因为其业务类别无效。</li> |
| 67 | +</ul> |
| 68 | +</div> |
| 69 | + |
| 70 | +<p> </p> |
| 71 | + |
| 72 | +<p><strong>提示:</strong></p> |
| 73 | + |
| 74 | +<ul> |
| 75 | + <li><code>n == code.length == businessLine.length == isActive.length</code></li> |
| 76 | + <li><code>1 <= n <= 100</code></li> |
| 77 | + <li><code>0 <= code[i].length, businessLine[i].length <= 100</code></li> |
| 78 | + <li><code>code[i]</code> 和 <code>businessLine[i]</code> 由可打印的 ASCII 字符组成。</li> |
| 79 | + <li><code>isActive[i]</code> 的值为 <code>true</code> 或 <code>false</code>。</li> |
| 80 | +</ul> |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +## 解题方法:分组 + 排序 |
| 85 | + |
| 86 | +> 分组/分类似乎差不多,暂不深究。 |
| 87 | +
|
| 88 | +使用4个数组,分别存放合法的4类优惠券。最后对4个数组分别按字符串字典序排序,合并为一个数组并返回。 |
| 89 | + |
| 90 | +如何判断一个优惠券是否合法? |
| 91 | + |
| 92 | +1. active为true |
| 93 | +2. businessLine属于4类之一 |
| 94 | +3. code不为空且只由数组字母下划线组成 |
| 95 | + |
| 96 | +注意,C++中合并vector时若被合并vector后续无需再使用,则可以使用make_move_iterator在内存上移动。 |
| 97 | + |
| 98 | ++ 时间复杂度$O(L\log n)$,其中$L$是合法code总字符数 |
| 99 | ++ 空间复杂度:C++$O(L)$ |
| 100 | + |
| 101 | +### AC代码 |
| 102 | + |
| 103 | +#### C++ |
| 104 | + |
| 105 | +```cpp |
| 106 | +/* |
| 107 | + * @LastEditTime: 2025-12-13 22:42:29 |
| 108 | + */ |
| 109 | +class Solution { |
| 110 | +private: |
| 111 | + inline bool is_ok(string& s) { |
| 112 | + for (char c : s) { |
| 113 | + if (c != '_' && !isalnum(c)) { |
| 114 | + return false; |
| 115 | + } |
| 116 | + } |
| 117 | + return !s.empty(); |
| 118 | + } |
| 119 | +public: |
| 120 | + vector<string> validateCoupons(vector<string>& code, vector<string>& businessLine, vector<bool>& isActive) { |
| 121 | + vector<string> electronics, grocery, pharmacy, restaurant; |
| 122 | + for (int i = 0; i < code.size(); i++) { |
| 123 | + if (!isActive[i]) { |
| 124 | + continue; |
| 125 | + } |
| 126 | + if (!is_ok(code[i])) { |
| 127 | + continue; |
| 128 | + } |
| 129 | + if (businessLine[i] == "electronics") { |
| 130 | + electronics.push_back(code[i]); |
| 131 | + } else if (businessLine[i] == "grocery") { |
| 132 | + grocery.push_back(code[i]); |
| 133 | + } else if (businessLine[i] == "pharmacy") { |
| 134 | + pharmacy.push_back(code[i]); |
| 135 | + } else if (businessLine[i] == "restaurant") { |
| 136 | + restaurant.push_back(code[i]); |
| 137 | + } |
| 138 | + } |
| 139 | + sort(electronics.begin(), electronics.end()); |
| 140 | + sort(grocery.begin(), grocery.end()); |
| 141 | + sort(pharmacy.begin(), pharmacy.end()); |
| 142 | + sort(restaurant.begin(), restaurant.end()); |
| 143 | + vector<string> ans; |
| 144 | + ans.reserve(electronics.size() + grocery.size() + pharmacy.size() + restaurant.size()); |
| 145 | + ans.insert(ans.end(), make_move_iterator(electronics.begin()), make_move_iterator(electronics.end())); |
| 146 | + ans.insert(ans.end(), make_move_iterator(grocery.begin()), make_move_iterator(grocery.end())); |
| 147 | + ans.insert(ans.end(), make_move_iterator(pharmacy.begin()), make_move_iterator(pharmacy.end())); |
| 148 | + ans.insert(ans.end(), make_move_iterator(restaurant.begin()), make_move_iterator(restaurant.end())); |
| 149 | + return ans; |
| 150 | + } |
| 151 | +}; |
| 152 | +``` |
| 153 | +
|
| 154 | +> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/155893803)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接](https://blog.letmefly.xyz/2025/12/13/LeetCode%203606.%E4%BC%98%E6%83%A0%E5%88%B8%E6%A0%A1%E9%AA%8C%E5%99%A8/)哦~ |
| 155 | +> |
| 156 | +> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode) |
0 commit comments