From 133fdb594dd3cf3d898d7143b0349fa86de6b4a0 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 9 Jul 2025 07:17:26 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3606 No.3606.Coupon Validator --- .../3606.Coupon Code Validator/README.md | 188 +++++++++++++++++- .../3606.Coupon Code Validator/README_EN.md | 188 +++++++++++++++++- .../3606.Coupon Code Validator/Solution.cpp | 38 ++++ .../3606.Coupon Code Validator/Solution.go | 42 ++++ .../3606.Coupon Code Validator/Solution.java | 39 ++++ .../3606.Coupon Code Validator/Solution.py | 19 ++ .../3606.Coupon Code Validator/Solution.ts | 30 +++ 7 files changed, 536 insertions(+), 8 deletions(-) create mode 100644 solution/3600-3699/3606.Coupon Code Validator/Solution.cpp create mode 100644 solution/3600-3699/3606.Coupon Code Validator/Solution.go create mode 100644 solution/3600-3699/3606.Coupon Code Validator/Solution.java create mode 100644 solution/3600-3699/3606.Coupon Code Validator/Solution.py create mode 100644 solution/3600-3699/3606.Coupon Code Validator/Solution.ts diff --git a/solution/3600-3699/3606.Coupon Code Validator/README.md b/solution/3600-3699/3606.Coupon Code Validator/README.md index 418bb16de8c1e..d586a85ca08fa 100644 --- a/solution/3600-3699/3606.Coupon Code Validator/README.md +++ b/solution/3600-3699/3606.Coupon Code Validator/README.md @@ -90,32 +90,212 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3606.Co -### 方法一 +### 方法一:模拟 + +我们可以直接模拟题目中的条件来筛选出有效的优惠券。具体步骤如下: + +1. **检查标识符**:对于每个优惠券的标识符,检查它是否非空,并且只包含字母、数字和下划线。 +2. **检查业务类别**:检查每个优惠券的业务类别是否属于给定的四个有效类别之一。 +3. **检查激活状态**:检查每个优惠券是否处于激活状态。 +4. **收集有效优惠券**:将所有满足上述条件的优惠券的 id 收集起来。 +5. **排序**:根据业务类别和标识符对有效优惠券进行排序。 +6. **返回结果**:返回排序后的有效优惠券的标识符列表。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$,其中 $n$ 是优惠券的数量。 #### Python3 ```python - +class Solution: + def validateCoupons( + self, code: List[str], businessLine: List[str], isActive: List[bool] + ) -> List[str]: + def check(s: str) -> bool: + if not s: + return False + for c in s: + if not (c.isalpha() or c.isdigit() or c == "_"): + return False + return True + + idx = [] + bs = {"electronics", "grocery", "pharmacy", "restaurant"} + for i, (c, b, a) in enumerate(zip(code, businessLine, isActive)): + if a and b in bs and check(c): + idx.append(i) + idx.sort(key=lambda i: (businessLine[i], code[i])) + return [code[i] for i in idx] ``` #### Java ```java - +class Solution { + public List validateCoupons(String[] code, String[] businessLine, boolean[] isActive) { + List idx = new ArrayList<>(); + Set bs + = new HashSet<>(Arrays.asList("electronics", "grocery", "pharmacy", "restaurant")); + + for (int i = 0; i < code.length; i++) { + if (isActive[i] && bs.contains(businessLine[i]) && check(code[i])) { + idx.add(i); + } + } + + idx.sort((i, j) -> { + int cmp = businessLine[i].compareTo(businessLine[j]); + if (cmp != 0) { + return cmp; + } + return code[i].compareTo(code[j]); + }); + + List ans = new ArrayList<>(); + for (int i : idx) { + ans.add(code[i]); + } + return ans; + } + + private boolean check(String s) { + if (s.isEmpty()) { + return false; + } + for (char c : s.toCharArray()) { + if (!Character.isLetterOrDigit(c) && c != '_') { + return false; + } + } + return true; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector validateCoupons(vector& code, vector& businessLine, vector& isActive) { + vector idx; + unordered_set bs = {"electronics", "grocery", "pharmacy", "restaurant"}; + + for (int i = 0; i < code.size(); ++i) { + const string& c = code[i]; + const string& b = businessLine[i]; + bool a = isActive[i]; + if (a && bs.count(b) && check(c)) { + idx.push_back(i); + } + } + + sort(idx.begin(), idx.end(), [&](int i, int j) { + if (businessLine[i] != businessLine[j]) return businessLine[i] < businessLine[j]; + return code[i] < code[j]; + }); + + vector ans; + for (int i : idx) { + ans.push_back(code[i]); + } + return ans; + } + +private: + bool check(const string& s) { + if (s.empty()) return false; + for (char c : s) { + if (!isalnum(c) && c != '_') { + return false; + } + } + return true; + } +}; ``` #### Go ```go +func validateCoupons(code []string, businessLine []string, isActive []bool) []string { + idx := []int{} + bs := map[string]struct{}{ + "electronics": {}, + "grocery": {}, + "pharmacy": {}, + "restaurant": {}, + } + + check := func(s string) bool { + if len(s) == 0 { + return false + } + for _, c := range s { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { + return false + } + } + return true + } + + for i := range code { + if isActive[i] { + if _, ok := bs[businessLine[i]]; ok && check(code[i]) { + idx = append(idx, i) + } + } + } + + sort.Slice(idx, func(i, j int) bool { + if businessLine[idx[i]] != businessLine[idx[j]] { + return businessLine[idx[i]] < businessLine[idx[j]] + } + return code[idx[i]] < code[idx[j]] + }) + + ans := make([]string, 0, len(idx)) + for _, i := range idx { + ans = append(ans, code[i]) + } + return ans +} +``` +#### TypeScript + +```ts +function validateCoupons(code: string[], businessLine: string[], isActive: boolean[]): string[] { + const idx: number[] = []; + const bs = new Set(['electronics', 'grocery', 'pharmacy', 'restaurant']); + + const check = (s: string): boolean => { + if (s.length === 0) return false; + for (let i = 0; i < s.length; i++) { + const c = s[i]; + if (!/[a-zA-Z0-9_]/.test(c)) { + return false; + } + } + return true; + }; + + for (let i = 0; i < code.length; i++) { + if (isActive[i] && bs.has(businessLine[i]) && check(code[i])) { + idx.push(i); + } + } + + idx.sort((i, j) => { + if (businessLine[i] !== businessLine[j]) { + return businessLine[i] < businessLine[j] ? -1 : 1; + } + return code[i] < code[j] ? -1 : 1; + }); + + return idx.map(i => code[i]); +} ``` diff --git a/solution/3600-3699/3606.Coupon Code Validator/README_EN.md b/solution/3600-3699/3606.Coupon Code Validator/README_EN.md index d87c733e4c078..6883dcc41ae6e 100644 --- a/solution/3600-3699/3606.Coupon Code Validator/README_EN.md +++ b/solution/3600-3699/3606.Coupon Code Validator/README_EN.md @@ -83,32 +83,212 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3606.Co -### Solution 1 +### Solution 1: Simulation + +We can directly simulate the conditions described in the problem to filter out valid coupons. The specific steps are as follows: + +1. **Check Identifier**: For each coupon's identifier, check whether it is non-empty and contains only letters, digits, and underscores. +2. **Check Business Category**: Check whether each coupon's business category belongs to one of the four valid categories. +3. **Check Activation Status**: Check whether each coupon is active. +4. **Collect Valid Coupons**: Collect the ids of all coupons that satisfy the above conditions. +5. **Sort**: Sort the valid coupons by business category and identifier. +6. **Return Result**: Return the list of identifiers of the sorted valid coupons. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$, where $n$ is the number of coupons. #### Python3 ```python - +class Solution: + def validateCoupons( + self, code: List[str], businessLine: List[str], isActive: List[bool] + ) -> List[str]: + def check(s: str) -> bool: + if not s: + return False + for c in s: + if not (c.isalpha() or c.isdigit() or c == "_"): + return False + return True + + idx = [] + bs = {"electronics", "grocery", "pharmacy", "restaurant"} + for i, (c, b, a) in enumerate(zip(code, businessLine, isActive)): + if a and b in bs and check(c): + idx.append(i) + idx.sort(key=lambda i: (businessLine[i], code[i])) + return [code[i] for i in idx] ``` #### Java ```java - +class Solution { + public List validateCoupons(String[] code, String[] businessLine, boolean[] isActive) { + List idx = new ArrayList<>(); + Set bs + = new HashSet<>(Arrays.asList("electronics", "grocery", "pharmacy", "restaurant")); + + for (int i = 0; i < code.length; i++) { + if (isActive[i] && bs.contains(businessLine[i]) && check(code[i])) { + idx.add(i); + } + } + + idx.sort((i, j) -> { + int cmp = businessLine[i].compareTo(businessLine[j]); + if (cmp != 0) { + return cmp; + } + return code[i].compareTo(code[j]); + }); + + List ans = new ArrayList<>(); + for (int i : idx) { + ans.add(code[i]); + } + return ans; + } + + private boolean check(String s) { + if (s.isEmpty()) { + return false; + } + for (char c : s.toCharArray()) { + if (!Character.isLetterOrDigit(c) && c != '_') { + return false; + } + } + return true; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector validateCoupons(vector& code, vector& businessLine, vector& isActive) { + vector idx; + unordered_set bs = {"electronics", "grocery", "pharmacy", "restaurant"}; + + for (int i = 0; i < code.size(); ++i) { + const string& c = code[i]; + const string& b = businessLine[i]; + bool a = isActive[i]; + if (a && bs.count(b) && check(c)) { + idx.push_back(i); + } + } + + sort(idx.begin(), idx.end(), [&](int i, int j) { + if (businessLine[i] != businessLine[j]) return businessLine[i] < businessLine[j]; + return code[i] < code[j]; + }); + + vector ans; + for (int i : idx) { + ans.push_back(code[i]); + } + return ans; + } + +private: + bool check(const string& s) { + if (s.empty()) return false; + for (char c : s) { + if (!isalnum(c) && c != '_') { + return false; + } + } + return true; + } +}; ``` #### Go ```go +func validateCoupons(code []string, businessLine []string, isActive []bool) []string { + idx := []int{} + bs := map[string]struct{}{ + "electronics": {}, + "grocery": {}, + "pharmacy": {}, + "restaurant": {}, + } + + check := func(s string) bool { + if len(s) == 0 { + return false + } + for _, c := range s { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { + return false + } + } + return true + } + + for i := range code { + if isActive[i] { + if _, ok := bs[businessLine[i]]; ok && check(code[i]) { + idx = append(idx, i) + } + } + } + + sort.Slice(idx, func(i, j int) bool { + if businessLine[idx[i]] != businessLine[idx[j]] { + return businessLine[idx[i]] < businessLine[idx[j]] + } + return code[idx[i]] < code[idx[j]] + }) + + ans := make([]string, 0, len(idx)) + for _, i := range idx { + ans = append(ans, code[i]) + } + return ans +} +``` +#### TypeScript + +```ts +function validateCoupons(code: string[], businessLine: string[], isActive: boolean[]): string[] { + const idx: number[] = []; + const bs = new Set(['electronics', 'grocery', 'pharmacy', 'restaurant']); + + const check = (s: string): boolean => { + if (s.length === 0) return false; + for (let i = 0; i < s.length; i++) { + const c = s[i]; + if (!/[a-zA-Z0-9_]/.test(c)) { + return false; + } + } + return true; + }; + + for (let i = 0; i < code.length; i++) { + if (isActive[i] && bs.has(businessLine[i]) && check(code[i])) { + idx.push(i); + } + } + + idx.sort((i, j) => { + if (businessLine[i] !== businessLine[j]) { + return businessLine[i] < businessLine[j] ? -1 : 1; + } + return code[i] < code[j] ? -1 : 1; + }); + + return idx.map(i => code[i]); +} ``` diff --git a/solution/3600-3699/3606.Coupon Code Validator/Solution.cpp b/solution/3600-3699/3606.Coupon Code Validator/Solution.cpp new file mode 100644 index 0000000000000..fa6f315cfe2ab --- /dev/null +++ b/solution/3600-3699/3606.Coupon Code Validator/Solution.cpp @@ -0,0 +1,38 @@ +class Solution { +public: + vector validateCoupons(vector& code, vector& businessLine, vector& isActive) { + vector idx; + unordered_set bs = {"electronics", "grocery", "pharmacy", "restaurant"}; + + for (int i = 0; i < code.size(); ++i) { + const string& c = code[i]; + const string& b = businessLine[i]; + bool a = isActive[i]; + if (a && bs.count(b) && check(c)) { + idx.push_back(i); + } + } + + sort(idx.begin(), idx.end(), [&](int i, int j) { + if (businessLine[i] != businessLine[j]) return businessLine[i] < businessLine[j]; + return code[i] < code[j]; + }); + + vector ans; + for (int i : idx) { + ans.push_back(code[i]); + } + return ans; + } + +private: + bool check(const string& s) { + if (s.empty()) return false; + for (char c : s) { + if (!isalnum(c) && c != '_') { + return false; + } + } + return true; + } +}; diff --git a/solution/3600-3699/3606.Coupon Code Validator/Solution.go b/solution/3600-3699/3606.Coupon Code Validator/Solution.go new file mode 100644 index 0000000000000..cfbcca0c20658 --- /dev/null +++ b/solution/3600-3699/3606.Coupon Code Validator/Solution.go @@ -0,0 +1,42 @@ +func validateCoupons(code []string, businessLine []string, isActive []bool) []string { + idx := []int{} + bs := map[string]struct{}{ + "electronics": {}, + "grocery": {}, + "pharmacy": {}, + "restaurant": {}, + } + + check := func(s string) bool { + if len(s) == 0 { + return false + } + for _, c := range s { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { + return false + } + } + return true + } + + for i := range code { + if isActive[i] { + if _, ok := bs[businessLine[i]]; ok && check(code[i]) { + idx = append(idx, i) + } + } + } + + sort.Slice(idx, func(i, j int) bool { + if businessLine[idx[i]] != businessLine[idx[j]] { + return businessLine[idx[i]] < businessLine[idx[j]] + } + return code[idx[i]] < code[idx[j]] + }) + + ans := make([]string, 0, len(idx)) + for _, i := range idx { + ans = append(ans, code[i]) + } + return ans +} diff --git a/solution/3600-3699/3606.Coupon Code Validator/Solution.java b/solution/3600-3699/3606.Coupon Code Validator/Solution.java new file mode 100644 index 0000000000000..a1aa9facfe19d --- /dev/null +++ b/solution/3600-3699/3606.Coupon Code Validator/Solution.java @@ -0,0 +1,39 @@ +class Solution { + public List validateCoupons(String[] code, String[] businessLine, boolean[] isActive) { + List idx = new ArrayList<>(); + Set bs + = new HashSet<>(Arrays.asList("electronics", "grocery", "pharmacy", "restaurant")); + + for (int i = 0; i < code.length; i++) { + if (isActive[i] && bs.contains(businessLine[i]) && check(code[i])) { + idx.add(i); + } + } + + idx.sort((i, j) -> { + int cmp = businessLine[i].compareTo(businessLine[j]); + if (cmp != 0) { + return cmp; + } + return code[i].compareTo(code[j]); + }); + + List ans = new ArrayList<>(); + for (int i : idx) { + ans.add(code[i]); + } + return ans; + } + + private boolean check(String s) { + if (s.isEmpty()) { + return false; + } + for (char c : s.toCharArray()) { + if (!Character.isLetterOrDigit(c) && c != '_') { + return false; + } + } + return true; + } +} diff --git a/solution/3600-3699/3606.Coupon Code Validator/Solution.py b/solution/3600-3699/3606.Coupon Code Validator/Solution.py new file mode 100644 index 0000000000000..c00bf99674476 --- /dev/null +++ b/solution/3600-3699/3606.Coupon Code Validator/Solution.py @@ -0,0 +1,19 @@ +class Solution: + def validateCoupons( + self, code: List[str], businessLine: List[str], isActive: List[bool] + ) -> List[str]: + def check(s: str) -> bool: + if not s: + return False + for c in s: + if not (c.isalpha() or c.isdigit() or c == "_"): + return False + return True + + idx = [] + bs = {"electronics", "grocery", "pharmacy", "restaurant"} + for i, (c, b, a) in enumerate(zip(code, businessLine, isActive)): + if a and b in bs and check(c): + idx.append(i) + idx.sort(key=lambda i: (businessLine[i], code[i])) + return [code[i] for i in idx] diff --git a/solution/3600-3699/3606.Coupon Code Validator/Solution.ts b/solution/3600-3699/3606.Coupon Code Validator/Solution.ts new file mode 100644 index 0000000000000..0a3abdf1b5fc7 --- /dev/null +++ b/solution/3600-3699/3606.Coupon Code Validator/Solution.ts @@ -0,0 +1,30 @@ +function validateCoupons(code: string[], businessLine: string[], isActive: boolean[]): string[] { + const idx: number[] = []; + const bs = new Set(['electronics', 'grocery', 'pharmacy', 'restaurant']); + + const check = (s: string): boolean => { + if (s.length === 0) return false; + for (let i = 0; i < s.length; i++) { + const c = s[i]; + if (!/[a-zA-Z0-9_]/.test(c)) { + return false; + } + } + return true; + }; + + for (let i = 0; i < code.length; i++) { + if (isActive[i] && bs.has(businessLine[i]) && check(code[i])) { + idx.push(i); + } + } + + idx.sort((i, j) => { + if (businessLine[i] !== businessLine[j]) { + return businessLine[i] < businessLine[j] ? -1 : 1; + } + return code[i] < code[j] ? -1 : 1; + }); + + return idx.map(i => code[i]); +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy