leetcode 18. 四数之和 && 拼车 && 航班预订统计 && 订会议室

  1. 四数之和
    使用四个指针(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;
    }
};
  1. 拼车
    第一步:第一步用字典记录(站点:净上车人数(上车为正,下车为负))
    第二部:依次从开始站点到结束,到每站累加并判断此时是否超过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;
    }
};
  1. 会议室 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值