LeetCode Weekly Contest 159-Part II
-
The contest consists of 4 problems: one easy, two medium and one hard problem.
-
This is part 2, one medium and one hard problems.
-
I was able to finish this problems after read through other’s solution…QAQ.
Problem 3: Replace the Substring for Balanced String
- How to solve:
- First initialize with: character count - (length / 4).
- Maintain two pointers to indicate interval of substring that needs to be replaced.
- Increment right pointer and decrease count of pointed char until there are no char count > 0.
- Increment left pointer and add back count of pointed char until there are no char count <= 0.
- Repeat 3&4. Terminate when right pointer reach the end of string.
- My solution after seeing the discussion:
- Runtime: 32ms
- Memory: 10 MB
class Solution {
public:
int balancedString(string s) {
int target = s.size() / 4;
vector<int> count (4, -target);
unordered_map<char, int> index ({{'Q',0}, {'W',1}, {'E',2}, {'R',3}});
int result = s.size();
for (int i = 0; i < s.size(); i++) {
count[index[s[i]]]++;
}
if (count[0] == 0 && count[1] == 0 && count[2] == 0 && count[3] == 0) return 0;
int start = 0;
int end = 0;
while (end < s.size()) {
while (end < s.size() && (count[0] > 0 || count[1] > 0 || count[2] > 0 || count[3] > 0)) {
count[index[s[end]]]--;
end++;
}
while (start <= end && count[0] <= 0 && count[1] <= 0 && count[2] <= 0 && count[3] <= 0) {
count[index[s[start]]]++;
start++;
}
if (end - start + 1 < result) {
result = end - start + 1;
}
}
return result;
}
};
- What I learn:
- Since we need to find consecutive interval(substring) to replace, we need to think of a sliding window.
- Since we can replace any char in the window, we need to focus on the char count outside the window.
Problem 4: Maximum Profit in Job Scheduling
- First think of dynamic programming, and I know we need a container to record max profit up to that time.
- But I cannot construct the formula all by myself.
-
I first try using vector and vector[i] is the max profit upto ith smallest endTime.
- How to solve: use map<endTime, max profit> to record
- Sort jobs by endTime.
- For each job, find the first record whose endTime > job startTime.
- Get the previous compatible profit + current job profit as P.
- Compare P with current max profit with latest endTime.
- If P is larger, record new <endTime, max profit> to the map.
- My solution:
- Runtime: 216ms
- Memory: 32.1 MB
class Solution {
public:
int jobScheduling(vector<int>& startTime, vector<int>& endTime, vector<int>& profit) {
map<int, int> max_profit {{0,0}}; // endTime, profit
vector<vector<int> > jobs;
int n = startTime.size();
for (int i = 0; i < n; i++) {
jobs.push_back({endTime[i], startTime[i], profit[i]});
}
sort(jobs.begin(), jobs.end());
vector<int> job;
for (int i = 0; i < n; i++) {
job = jobs[i];
/* 1. max_profit.upper_bound(job[1]): find the first endTime that > job startTime
2. prev: get previous iterator of 1.
3. ->second: get its profit
===> Previous compatible profit + job[2] (new task profit)
*/
int cur = prev(max_profit.upper_bound(job[1]))->second + job[2];
// compare current profit to current maximum profit
if (cur > max_profit.rbegin()->second) {
// New job has larger endTime, only add to map if profit more.
max_profit[job[0]] = cur;
}
}
return max_profit.rbegin()->second;
}
};
- What I learn:
- From the discussion, this is similar to the knapsack problem.
- Needs to utilize STL binary search function to get upper/lower bound of some value.
- Use upper_bound to find previous compatible tasks. (if all tasks are compatible, then return the last.)
- map if the OrderedDict in python, its keys are ordered as they are inserted.
- Wrapping up:
- The goal for participating the weekly contest is to motivate me to improve my data structure and algorithm skills.
- Data structure and algorithms are essential for programmers.
- Hope I can learn more and improve more from these contests!!