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 between1
and10
. - Each
{time}
consist of digits, and represent an integer between0
and1000
. - Each
{amount}
consist of digits, and represent an integer between0
and2000
.
這道題讓找出所有非法的交易,這里的交易是由四個信息組成的,名稱,時間,金額,和地點。這里定義的非法交易有兩種情況,一種是金額大於 1000 的,另一種是跟任意一個相同名字但在其他城市的交易且在 60 分鍾內發生的。這道題還是主要考察字符串的處理,信息都在一個字符串中,肯定要把它們提取出來,Java 中可以直接調用 split 函數,而 C++ 中只好使用字符串流來處理了,將四個信息拆分到不同的字符串中,然后直接判斷拆分出的交易額,若大於 1000,加入到一個 HashSet 中,這里用 HashSet 是因為判斷第二個非法條件時候去重復用。第二個非法條件是說相同名字,且在不同城市,比較好的處理方法就是進行分類,將所有相同名字的交易都放到同一個數組中,即建立名字和其對應的交易數組之間的映射,這里的每個交易還是保存的是拆分好的交易信息數組。現在遍歷所有相同名字的交易,若城市不同,且交易時間在 60 分鍾內,則將這兩個互相比較的交易都加入 HashSet,現在就知道為啥使用 HashSet 了,因為可以去重復。每次記得要把當前拆分好的交易信息加入到 HashMap 對應的位置。這道題后來的 Test Cases 加入了相同交易,四個信息完全相同,雖然不會觸發第二個非法條件,但是有可能都觸發第一個非法條件,即交易額大於 1000,那么這兩個完全相同的交易就都要出現在返回數組中,但由於前面我們定義的是用 HashSet,不能有重復項,怎么辦呢?這里用個 trick,首先在遍歷中就統計出每個相同的交易出現的次數,這樣只要該交易在最后的 HashSet 中,就表示跟其所有相同的交易都應該在結果中,將其總出現次數減1次加入到結果 res 中即可,參見代碼如下:
class Solution {
public:
vector<string> invalidTransactions(vector<string>& transactions) {
vector<string> res;
unordered_set<string> st;
unordered_map<string, vector<vector<string>>> m;
unordered_map<string, int> cntMap;
for (string t : transactions) {
++cntMap[t];
istringstream iss(t);
vector<string> vec(4);
int i = 0;
while (getline(iss, vec[i++], ','));
if (stoi(vec[2]) > 1000) st.insert(t);
for (auto &a : m[vec[0]]) {
if (a[3] != vec[3] && abs(stoi(a[1]) - stoi(vec[1])) <= 60) {
st.insert(a[0] + "," + a[1] + "," + a[2] + "," + a[3]);
if (!st.count(t)) st.insert(t);
}
}
m[vec[0]].push_back(vec);
}
for (auto &a : cntMap) {
if (st.count(a.first)) {
for (int i = 0; i < a.second - 1; ++i) {
res.push_back(a.first);
}
}
}
res.insert(res.end(), st.begin(), st.end());
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1169
參考資料:
https://leetcode.com/problems/invalid-transactions/
https://leetcode.com/problems/invalid-transactions/discuss/366414/C%2B%2B-Hashtable