Use a HashSet to record all paths that have appeared, then traverse all paths and decompose each level of parent directories one by one, checking whether they appear in the record.
Time complexity: O(folder.size() * string.size()), space complexity: O(folder.size() * string.size()).
classSolution { public: vector<string> removeSubfolders(vector<string>& folder){ unordered_set<string> memo; for (auto& f : folder) { memo.insert(f); } vector<string> ans; for (auto& f : folder) { int i = f.size() - 1; bool appear = false; while (i >= 0) { while (i >= 0 && f[i] != '/') { --i; } auto head = f.substr(0, i); if (memo.find(head) != memo.end()) { appear = true; break; } --i; } if (!appear) { ans.push_back(f); } } return ans; } };
1234. Replace the Substring for Balanced String
Sliding window. Record all extra letters, then set up a window such that the number of occurrences of the extra letters inside the window is greater than or equal to the extra count. Then move this window while keeping that property unchanged. Record the minimum window length.
classSolution { using ll = longlong; public: intbalancedString(string s){ auto charaters = {'Q', 'W', 'E', 'R'}; unordered_map<char, ll> count; for (char c : s) { ++count[c]; } ll target = s.size() / 4; ll window_size = 0; unordered_set<char> one; for (constauto& p : count) { // cout << p.first << ", " << p.second << endl; if (p.second > target) { window_size += p.second - target; one.insert(p.first); } } if (window_size == 0) return0; ll i = 0; unordered_map<char, ll> one_amount; while (i < s.size()) { if (all_of(one.begin(), one.end(), [&](constauto& p) -> bool { return one_amount[p] >= count[p] - target; })) { break; } if (one.find(s[i]) != one.end()) { ++one_amount[s[i]]; } ++i; } ll left = 0; while (left < s.size() && (one.find(s[left]) != one.end() && one_amount[s[left]] > count[s[left]] - target) || (one.find(s[left]) == one.end())) { --one_amount[s[left]]; ++left; } ll ret = i - left; for (; i < s.size(); ++i) { if (one.find(s[i]) != one.end()) { ++one_amount[s[i]]; while (left < s.size() && (one.find(s[left]) != one.end() && one_amount[s[left]] > count[s[left]] - target) || (one.find(s[left]) == one.end())) { --one_amount[s[left]]; ++left; } } ret = min(ret, i - left + 1); } return ret; } };
1235. Maximum Profit in Job Scheduling
Similar to a knapsack problem. First sort jobs by endTime. Traverse each job, decide whether to include it, and update the total profit. The update strategy is: according to the job’s start_time, use binary search to find a valid end_time, and obtain the maximum profit if this job is included. If the maximum profit is greater than the previous maximum profit for end_time - because jobs have already been sorted by end_time, we can guarantee that the job’s end_time is the end_time that obtains the maximum profit - then update profit. Finally return the profit of the largest end_time.
Time complexity: O(N log N), space complexity: O(N).