六月集训代码打卡---DAY3

前言

        来自 英雄哪里出来 的一个 免费 集训,每天 5 5 5 点打卡学习算法(我是为了卷吗,主要是想早起 😏),希望能坚持下去。这里用来复盘每天都的打卡题目。
       今日份知识点:排序

一、题目

题目难度
1464. 数组中两元素的最大乘积⭐️
1636. 按照频率将数组升序排序⭐️
1287. 有序数组中出现次数超过25%的元素⭐️
436. 寻找右区间⭐️⭐️

二、算法思路

1、数组中两元素的最大乘积

        (1)对数组进行排序,直接返回最后两个数 减1 的差的积。

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return (nums[nums.size() - 1] - 1) * (nums[nums.size() - 2] - 1);
    }
};

2、按照频率将数组升序排序

        (1)建立一个计数数组,然后遍历数组统计每个数字的频率。
        (2)排序数组,通过一个 匿 名 函 数 匿名函数 规定排序的规则。
        (3)注意:数字存在 负 数 负数 ,需要对数字加上一个偏移量。

class Solution {
public:
    #define base 100
    vector<int> frequencySort(vector<int>& nums) {
        int t[210];
        memset(t, 0, sizeof t);
        for (int i = 0; i < nums.size(); ++ i)
            t[nums[i] + base] ++;
        sort(nums.begin(), nums.end(), [&] (const int& a, const int& b) {
            if (t[a + base] != t[b + base])
                return t[a + base] < t[b + base];
            return a > b;
        });
        return nums;
    }
};

3、有序数组中出现次数超过25%的元素

        (1)首先对数组排序,然后遍历数组,计算相同数字出现的次数,如果大于数组长度的 1 4 \frac{1}{4} 41,那么返回对应数字即可。
        (2)数组排序过后,相同的数字会放到一起,只需要比较是否与前一个数字一样即可。

class Solution {
public:
    int findSpecialInteger(vector<int>& arr) {
        sort(arr.begin(), arr.end());
        int cnt = 1;
        for (int i = 1; i < arr.size(); ++ i) {
            if (arr[i] == arr[i - 1])
                ++ cnt;
            else {
                cnt = 1;
                continue;
            }
            if (cnt * 4 > arr.size())
                return arr[i];
        }
        return arr[0];
    }
};

4、寻找右区间

        (1)我们需要的是 最 小 左 端 点 最小左端点 ,所以建立一个索引数组 t t t,保存每个区间的左端点以及各自的下标;
        (2)对索引数组排序(pair的排序默认先按first的字典序,如果相同再比较second);
        (3)遍历数组,然后通过二分寻找比当前区间右端点大的最小做端点,保存下标;
        (4)注意:这里用到的二分模板是l <= r,所以二分结束后的是否符合条件需要特别说明。当前区间的左端点是最大的 — l 会超出边界;当前区间的左端点是最小的 — 那么当前得到的 l 对应索引的区间一定不符合要求。

class Solution {
public:
    vector<int> findRightInterval(vector<vector<int>>& intervals) {
        vector<pair<int, int>> t;
        for (int i = 0; i < intervals.size(); ++ i) {
            t.push_back({intervals[i][0], i});
        }
        sort(t.begin(), t.end());
        vector<int> ret;
        for (int i = 0; i < intervals.size(); ++ i) {
            int l = 0, r = t.size() - 1;
            while (l <= r) {
                int mid = (l + r) >> 1;
                if (t[mid].first < intervals[i][1])
                    l = mid + 1;
                else
                    r = mid - 1;
            }
            if (l == t.size() || t[l].first < intervals[i][1])
                ret.push_back(-1);
            else
                ret.push_back(t[l].second);
        }
        return ret;
    }
};

结语

主要熟悉 sort 函数的写法以及 匿 名 函 数 匿名函数 的书写格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值