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.