## 1169. Invalid Transactions

A transaction is possibly invalid if:

• the amount exceeds `\$1000`, or;
• if it occurs within (and including) `60` minutes of another transaction with the same name in a different city.

You are given an array of strings `transaction` where `transactions[i]` consists of comma-separated values representing the name, time (in minutes), amount, and city of the transaction.

Return a list of `transactions` that are possibly invalid. You may return the answer in any order.

Example 1:

```Input: transactions = ["alice,20,800,mtv","alice,50,100,beijing"]
Output: ["alice,20,800,mtv","alice,50,100,beijing"]
Explanation: The first transaction is invalid because the second transaction occurs within a difference of 60 minutes, have the same name and is in a different city. Similarly the second one is invalid too.```

Example 2:

```Input: transactions = ["alice,20,800,mtv","alice,50,1200,mtv"]
Output: ["alice,50,1200,mtv"]
```

Example 3:

```Input: transactions = ["alice,20,800,mtv","bob,50,1200,mtv"]
Output: ["bob,50,1200,mtv"]
```

Constraints:

• `transactions.length <= 1000`
• Each `transactions[i]` takes the form `"{name},{time},{amount},{city}"`
• Each `{name}` and `{city}` consist of lowercase English letters, and have lengths between `1` and `10`.
• Each `{time}` consist of digits, and represent an integer between `0` and `1000`.
• Each `{amount}` consist of digits, and represent an integer between `0` and `2000`.

## Rust Solution

``````struct Solution;
use std::collections::HashMap;
use std::collections::HashSet;

impl Solution {
fn invalid_transactions(transactions: Vec<String>) -> Vec<String> {
let n = transactions.len();
let mut hm: HashMap<String, Vec<(i32, String, String)>> = HashMap::new();
let mut hs: HashSet<String> = HashSet::new();
for i in 0..n {
let transaction = &transactions[i];
let mut v: Vec<String> = transaction
.split_terminator(',')
.map(|s| s.to_string())
.collect();
let city = v.pop().unwrap();
let amount = v.pop().unwrap().parse::<i32>().unwrap();
let time = v.pop().unwrap().parse::<i32>().unwrap();
let name = v.pop().unwrap();
hm.entry(name)
.or_default()
.push((time, city, transaction.clone()));
if amount > 1000 {
hs.insert(transactions[i].clone());
}
}
for transactions in hm.values() {
let n = transactions.len();
for i in 0..n {
for j in i + 1..n {
let ti = &transactions[i];
let tj = &transactions[j];
if (ti.0 - tj.0).abs() <= 60 && ti.1 != tj.1 {
hs.insert(ti.2.clone());
hs.insert(tj.2.clone());
}
}
}
}
hs.drain().collect()
}
}

#[test]
fn test() {
let transactions = vec_string!["alice,20,800,mtv", "alice,50,100,beijing"];
let mut res = vec_string!["alice,20,800,mtv", "alice,50,100,beijing"];
let mut ans = Solution::invalid_transactions(transactions);
res.sort();
ans.sort();
assert_eq!(ans, res);
let transactions = vec_string!["alice,20,800,mtv", "alice,50,1200,mtv"];
let mut res = vec_string!["alice,50,1200,mtv"];
let mut ans = Solution::invalid_transactions(transactions);
res.sort();
ans.sort();
assert_eq!(ans, res);
let transactions = vec_string!["alice,20,800,mtv", "bob,50,1200,mtv"];
let mut res = vec_string!["bob,50,1200,mtv"];
let mut ans = Solution::invalid_transactions(transactions);
res.sort();
ans.sort();
assert_eq!(ans, res);
}
``````

Having problems with this solution? Click here to submit an issue on github.