mirror of https://github.com/doocs/leetcode.git
feat: add solutions to lc problem: No.3606 (#4558)
No.3606.Coupon Validator
This commit is contained in:
parent
55d4ea1ff0
commit
d7fddea9a6
|
|
@ -90,32 +90,212 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3606.Co
|
|||
|
||||
<!-- solution:start -->
|
||||
|
||||
### 方法一
|
||||
### 方法一:模拟
|
||||
|
||||
我们可以直接模拟题目中的条件来筛选出有效的优惠券。具体步骤如下:
|
||||
|
||||
1. **检查标识符**:对于每个优惠券的标识符,检查它是否非空,并且只包含字母、数字和下划线。
|
||||
2. **检查业务类别**:检查每个优惠券的业务类别是否属于给定的四个有效类别之一。
|
||||
3. **检查激活状态**:检查每个优惠券是否处于激活状态。
|
||||
4. **收集有效优惠券**:将所有满足上述条件的优惠券的 id 收集起来。
|
||||
5. **排序**:根据业务类别和标识符对有效优惠券进行排序。
|
||||
6. **返回结果**:返回排序后的有效优惠券的标识符列表。
|
||||
|
||||
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$,其中 $n$ 是优惠券的数量。
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### 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<String> validateCoupons(String[] code, String[] businessLine, boolean[] isActive) {
|
||||
List<Integer> idx = new ArrayList<>();
|
||||
Set<String> 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<String> 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<string> validateCoupons(vector<string>& code, vector<string>& businessLine, vector<bool>& isActive) {
|
||||
vector<int> idx;
|
||||
unordered_set<string> 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<string> 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]);
|
||||
}
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
|
|
|||
|
|
@ -83,32 +83,212 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3606.Co
|
|||
|
||||
<!-- solution:start -->
|
||||
|
||||
### 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.
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### 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<String> validateCoupons(String[] code, String[] businessLine, boolean[] isActive) {
|
||||
List<Integer> idx = new ArrayList<>();
|
||||
Set<String> 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<String> 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<string> validateCoupons(vector<string>& code, vector<string>& businessLine, vector<bool>& isActive) {
|
||||
vector<int> idx;
|
||||
unordered_set<string> 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<string> 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]);
|
||||
}
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
class Solution {
|
||||
public:
|
||||
vector<string> validateCoupons(vector<string>& code, vector<string>& businessLine, vector<bool>& isActive) {
|
||||
vector<int> idx;
|
||||
unordered_set<string> 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<string> 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;
|
||||
}
|
||||
};
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
class Solution {
|
||||
public List<String> validateCoupons(String[] code, String[] businessLine, boolean[] isActive) {
|
||||
List<Integer> idx = new ArrayList<>();
|
||||
Set<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]);
|
||||
}
|
||||
Loading…
Reference in New Issue