LeetCode-排序篇

1086.前五科的平均分数

给你一个不同学生的分数列表,请按 学生的 id 顺序 返回每个学生最高的五科 成绩的 平均分。对于每条 items[i] 记录, items[i][0] 为学生的 id,items[i][1] 为学生的分数。平均分请采用整数除法计算。

思路
先按学号从小到大排序,学号相同则按分数大到小排序

static bool compare(vector<int> &a, vector<int> &b) {
   
        if(a[0] < b[0])
            return true;
        if(a[0] > b[0])
            return false;
        return a[1] > b[1];
    }
    vector<vector<int>> highFive(vector<vector<int>>& items) {
   
        sort(items.begin(), items.end(), compare);
        vector<vector<int>> ans;
        int cout = 0;
        int sum = 0;
        for (int i = 0 ; i < items.size(); i++) {
   
            if (cout < 5) {
   
                sum += items[i][1];
                cout++;
            }
            if ( i == (items.size() - 1) || items[i][0] != items[i+1][0] ) {
   
                vector<int> vt ;
                vt.push_back(items[i-1][0]);
                vt.push_back(sum / cout);
                ans.push_back(vt);
                cout = 0;
                sum = 0;
            }
        }
        return ans;
    }

252.会议室

给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),请你判断一个人是否能够参加这里面的全部会议。
示例 1:
输入: [[0,30],[5,10],[15,20]]
输出: false
示例 2:
输入: [[7,10],[2,4]]
输出: true

思路
首先根据[0]值从小到大排序
然后如果第二个值的[0] < 第一个值的[1] 则表示冲突

static bool compare(vector<int> &a, vector<int> &b) {
   
        if (a[0] > b[0]) return false;
        return true;
    }
    bool canAttendMeetings(vector<vector<int>>& intervals) {
   
        sort(intervals.begin(), intervals.end(), compare);
        for (int i = 1; i < intervals.size(); i++) {
   
            if (intervals[i-1][1] > intervals[i][0]) return false;
        }

        return true;
    }

253.会议室II

给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。
示例 1:
输入: [[0, 30],[5, 10],[15, 20]]
输出: 2
示例 2:
输入: [[7,10],[2,4]]
输出: 1

思路
首先根据[0]进行从小到大排序,然后按[1]进入小顶堆
此时小顶堆上的[1]是结束时间最短的
然后新元素的开始时间[0]与小顶堆堆顶比较,如果是大于小顶堆,那么就pop堆顶,新元素进堆,因为开始时间>结束时间所以可以视为是同个会议室
计算堆里元素即为会议室个数

static bool cmp(vector<int>a, vector<int> b){
   
        return a[0] < b[0];
}
int minMeetingRooms(vector<vector<int>>& intervals) {
   
        if(intervals.size() == 0 || intervals[0].size() == 0)
            return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        // greater表示是小顶堆
        priority_queue<int, vector<int>, greater<int>> occupied;   
        for(auto meet:intervals){
   
            // 堆顶是结束时间最前的
            // 新元素的开始时间 > 堆顶结束时间就说明这两个可以同个会议室
            if(!occupied.empty() && occupied.top() <= meet[0]) {
   
                occupied.pop();
            }  
            occupied.push(meet[1]);  //当前会议结束时间入队
        }
        return occupied.size();
}

280.摆动排序

给你一个无序的数组 nums, 将该数字 原地 重排后使得 nums[0] <= nums[1] >= nums[2] <= nums[3]…。

示例:
输入: nums = [3,5,2,1,6,4]
输出: 一个可能的解答是 [3,5,1,6,2,4]

思路
1:先排序,然后根据下标偶数的时候与后面一个换一下
2:不需要先排序,下标奇数的时候判断时候>=下一个,如果不是就互换

void swap(vector<int>& nums,int i,int j) {
   
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    void wiggleSort(vector<int>& nums) {
   
        for (int i = 1; i < nums.size(); i++) {
   
            //偶数的时候,如果大于后者,那么就需要换
            // 奇数的时候,如果小于后者,那么就需要换
            if ((i % 2 == 0 && nums[i] > nums[i - 1]) || (i % 2 == 1 && nums[i] < nums[i - 1])) {
   
                swap(nums,i,i - 1);
            }
        }
    }

324.摆动排序II

给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。

示例 1:
输入: nums = [1, 5, 1, 1, 6, 4]
输出: 一个可能的答案是 [1, 4, 1, 5, 1, 6]
示例 2:
输入: nums = [1, 3, 2, 2, 3, 1]
输出: 一个可能的答案是 [2, 3, 1, 3, 1, 2]

思路
先进行排序,然后将数组分两部分,根据index的奇偶,在偶数的时候从前部分最后一个放数组[0]位置,奇数就后半部分最后一个放数组[1]
这样就能变成 [0]<[1]>[2]<[3]

void wiggleSort(vector<int>& nums) {
   
        int size = nums.size();
        vector<int> tmp(nums);
         //size+1原因是前部分较小,数量比后半段多1个情况下可以放两边
         // 如果后半段多的话放不了
         //如12121, 1有3个,2有2个. 11122则mid要[2]才可以
        int end = size-1, mid = (size + 1) / 2 - 1;
        sort(tmp.begin(), tmp.end());
        for (int i = 0; i < size; ++i) {
   
            nums[i] = i % 2 == 0 ? tmp[mid--] : tmp[end--];
        }
    }

1057.校园自行车分配

在由 2D 网格表示的校园里有 n 位工人(worker)和 m 辆自行车(bike),n <= m。
所有工人和自行车的位置都用网格上的 2D 坐标表示。
我们需要为每位工人分配一辆自行车。在所有可用的自行车和工人中,我们选取彼此之间曼哈顿距离最短的工人自行车对 (worker, bike) ,并将其中的自行车分配給工人。如果有多个 (worker, bike) 对之间的曼哈顿距离相同,那么我们选择工人索引最小的那对。类似地,如果有多种不同的分配方法,则选择自行车索引最小的一对。不断重复这一过程,直到所有工人都分配到自行车为止。
给定两点 p1 和 p2 之间的
曼哈顿距离为 Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|。
返回长度为 n 的向量 ans,其中 a[i] 是第 i 位工人分配到的自行车的索引(从 0 开始)。

示例
在这里插入图片描述
输入:workers = [[0,0],[1,1],[2,0]], bikes = [[1,0],[2,2],[2,1]]
输出:[0,2,1]
解释:
工人 0 首先分配到自行车 0 。工人 1 和工人 2 与自行车 2 距离相同,因此工人 1 分配到自行车 2,工人 2 将分配到自行车 1 。因此输出为 [0,2,1]。

思路
首先计算每个worker到bike的距离d,然后将d为key,worker_id和bike_id存到Map中
然后遍历这个Map,遍历是从0开始的,所以是距离最短的先

vector<int> assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) {
   
        vector<int> ans(workers.size());
        //key是d
        //pair:worker_id , bike_id
        map<int, vector<pair<int, int>>> distMap;
        vector&l
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值