- 四数之和
使用四个指针(a<b<c<d)。固定最小的a和b在左边,c=b+1,d=_size-1 移动两个指针包夹求解。
保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。偏大时d左移,偏小时c右移。c和d相
遇时,表示以当前的a和b为最小值的解已经全部求得。b++,进入下一轮循环b循环,当b循环结束后。
a++,进入下一轮a循环。 即(a在最外层循环,里面嵌套b循环,再嵌套双指针c,d包夹求解)。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> out;
sort(nums.begin(), nums.end());
int N = nums.size();
if (N < 4) {
return out;
}
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
int start = j + 1; // key1
int end = N - 1;
while (start < end) {
int sum = nums[i] + nums[j] + nums[start] + nums[end];
if (sum == target) {
bool repeat = false;
for (int k = (int)(out.size()) - 1; k >= 0; k--) { // key2 去重
if (out[k][0] == nums[i] && out[k][1] == nums[j] && out[k][2] == nums[start] && out[k][3] == nums[end]) {
repeat = true;
break;
}
}
if (!repeat) {
out.push_back({nums[i], nums[j], nums[start], nums[end]});
}
start++;
} else if (sum < target) {
start++;
} else { // sum > target
end--;
}
}
}
}
return out;
}
};
- 拼车
第一步:第一步用字典记录(站点:净上车人数(上车为正,下车为负))
第二部:依次从开始站点到结束,到每站累加并判断此时是否超过capacity,是则立即return False;否则循环完后,True
class Solution {
public:
bool carPooling(vector<vector<int>>& trips, int capacity) {
unordered_map<int, int> mp;
set<int> s;
for (auto i : trips) {
if (mp.find(i[1]) != mp.end()) {
mp[i[1]] += i[0];
} else {
mp[i[1]] = i[0];
}
if (mp.find(i[2]) != mp.end()) {
mp[i[2]] -= i[0];
} else {
mp[i[2]] = -i[0];
}
s.insert(i[1]);
s.insert(i[2]);
}
int sum = 0;
set<int>::iterator i;
for (i = s.begin(); i != s.end(); i++) {
sum += mp[*i];
if (sum > capacity) {
return false;
}
}
return true;
}
};
方法类似拼车
class Solution {
public:
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
unordered_map<int, int> mp;
for (auto booking : bookings) {
if (mp.find(booking[0]) != mp.end()) {
mp[booking[0]] += booking[2];
} else {
mp[booking[0]] = booking[2];
}
if (booking[1] + 1 <= n) {
if (mp.find(booking[1] + 1) != mp.end()) {
mp[booking[1] + 1] -= booking[2];
} else {
mp[booking[1] + 1] = -booking[2];
}
}
}
vector<int> out;
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += mp[i];
out.push_back(sum);
}
return out;
}
};
- 会议室 II
给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。
思路:总体思路类似前面两题,但是这次用了map(内部用红黑树实现了按键值从小到大排序的功能),使得后续操作方便了很多。
class Solution {
public:
int minMeetingRooms(vector<vector<int>>& intervals) {
map<int, int> M; // key1:内部用红黑树实现了按键值从小到大排序
for (auto i : intervals) {
if (M.find(i[0]) != M.end()) {
M[i[0]]++;
} else {
M[i[0]] = 1;
}
if (M.find(i[1]) != M.end()) {
M[i[1]]--;
} else {
M[i[1]] = -1;
}
}
int out = 0;
int sum = 0;
for (auto i : M) {
sum += i.second; // key1:内部用红黑树实现了按键值从小到大排序
out = max(sum, out);
}
return out;
}
};