LeetCode: 第 51 场双周赛(携程集团)题解

5730. 将所有数字用字符替换

给你一个下标从 0 开始的字符串 s ,它的 偶数 下标处为小写英文字母,奇数 下标处为数字。

定义一个函数 shift(c, x) ,其中 c 是一个字符且 x 是一个数字,函数返回字母表中 c 后面第 x 个字符。

比方说,shift(‘a’, 5) = ‘f’ 和 shift(‘x’, 0) = ‘x’ 。
对于每个 奇数 下标 i ,你需要将数字 s[i] 用 shift(s[i-1], s[i]) 替换。

请你替换所有数字以后,将字符串 s 返回。题目 保证 shift(s[i-1], s[i]) 不会超过 ‘z’ 。

示例 1:
输入:s = “a1c1e1”
输出:“abcdef”
解释:数字被替换结果如下:

  • s[1] -> shift(‘a’,1) = ‘b’
  • s[3] -> shift(‘c’,1) = ‘d’
  • s[5] -> shift(‘e’,1) = ‘f’
    示例 2:
    输入:s = “a1b2c3d4e”
    输出:“abbdcfdhe”
    解释:数字被替换结果如下:
  • s[1] -> shift(‘a’,1) = ‘b’
  • s[3] -> shift(‘b’,2) = ‘d’
  • s[5] -> shift(‘c’,3) = ‘f’
  • s[7] -> shift(‘d’,4) = ‘h’

提示:
1 <= s.length <= 100
s 只包含小写英文字母和数字。
对所有 奇数 下标处的 i ,满足 shift(s[i-1], s[i]) <= ‘z’ 。

题解

#include 
#include 
#include 
#include 
#include 
//#include 
using namespace std;

class Solution {
     
public:
    unordered_map<char,int> mp = {
     {
     'a',0},{
     'b',1},{
     'c',2},{
     'd',3},{
     'e',4},{
     'f',5},
                                  {
     'g',6},{
     'h',7},{
     'i',8},{
     'j',9},{
     'k',10},{
     'l',11},
                                  {
     'm',12},{
     'n',13},{
     'o',14},{
     'p',15},{
     'q',16},{
     'r',17},
                                  {
     's',18},{
     't',19},{
     'u',20},{
     'v',21},{
     'w',22},{
     'x',23},
                                  {
     'y',24},{
     'z',25}};
    vector<char> cc = {
     'a','b','c','d','e','f','g','h','i','j','k','l',
                       'm','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    char shift(char c, int i){
     
        int id = mp[c];
        return cc[id+i];
    }
    string replaceDigits(string s) {
     
        int n = s.size();
        for(int i = 1; i < n; i += 2){
     
            s[i] = shift(s[i-1],s[i]-'0');
        }
        return s;
    }
};

int main() {
     
    Solution s;
    string str = "a1b2c3d4e";
    string result = s.replaceDigits( str);
    for(int i = 0; i < result.size();i++){
     
        cout << result[i];
    }
    return 0;
}

5731. 座位预约管理系统

请你设计一个管理 n 个座位预约的系统,座位编号从 1 到 n 。

请你实现 SeatManager 类:

SeatManager(int n) 初始化一个 SeatManager 对象,它管理从 1 到 n 编号的 n 个座位。所有座位初始都是可预约的。
int reserve() 返回可以预约座位的 最小编号 ,此座位变为不可预约。
void unreserve(int seatNumber) 将给定编号 seatNumber 对应的座位变成可以预约。

示例 1:
输入:
[“SeatManager”, “reserve”, “reserve”, “unreserve”, “reserve”, “reserve”, “reserve”, “reserve”, “unreserve”]
[[5], [], [], [2], [], [], [], [], [5]]
输出:
[null, 1, 2, null, 2, 3, 4, 5, null]
解释:
SeatManager seatManager = new SeatManager(5); // 初始化 SeatManager ,有 5 个座位。
seatManager.reserve(); // 所有座位都可以预约,所以返回最小编号的座位,也就是 1 。
seatManager.reserve(); // 可以预约的座位为 [2,3,4,5] ,返回最小编号的座位,也就是 2 。
seatManager.unreserve(2); // 将座位 2 变为可以预约,现在可预约的座位为 [2,3,4,5] 。
seatManager.reserve(); // 可以预约的座位为 [2,3,4,5] ,返回最小编号的座位,也就是 2 。
seatManager.reserve(); // 可以预约的座位为 [3,4,5] ,返回最小编号的座位,也就是 3 。
seatManager.reserve(); // 可以预约的座位为 [4,5] ,返回最小编号的座位,也就是 4 。
seatManager.reserve(); // 唯一可以预约的是座位 5 ,所以返回 5 。
seatManager.unreserve(5); // 将座位 5 变为可以预约,现在可预约的座位为 [5] 。

提示:
1 <= n <= 105
1 <= seatNumber <= n
每一次对 reserve 的调用,题目保证至少存在一个可以预约的座位。
每一次对 unreserve 的调用,题目保证 seatNumber 在调用函数前都是被预约状态。
对 reserve 和 unreserve 的调用 总共 不超过 105 次。

题解

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

class SeatManager {
     
public:
    //unordered_map seat;
    priority_queue<int,vector<int>,greater<int>> q;
    vector<int> res;
    SeatManager(int n) {
     
        for(int i = 0; i < n; i++){
     
            //seat[i] = i+1;
            //q.push(seat[i]);
            q.push(i+1);
        }
    }
    int reserve() {
     
        int r = q.top();
        q.pop();
        return r;
    }

    void unreserve(int seatNumber) {
     
        q.push(seatNumber);
    }
};

/**
 * Your SeatManager object will be instantiated and called as such:
 * SeatManager* obj = new SeatManager(n);
 * int param_1 = obj->reserve();
 * obj->unreserve(seatNumber);
 */

5732. 减小和重新排列数组后的最大元素

给你一个正整数数组 arr 。请你对 arr 执行一些操作(也可以不进行任何操作),使得数组满足以下条件:

arr 中 第一个 元素必须为 1 。
任意相邻两个元素的差的绝对值 小于等于 1 ,也就是说,对于任意的 1 <= i < arr.length (数组下标从 0 开始),都满足 abs(arr[i] - arr[i - 1]) <= 1 。abs(x) 为 x 的绝对值。
你可以执行以下 2 种操作任意次:

减小 arr 中任意元素的值,使其变为一个 更小的正整数 。
重新排列 arr 中的元素,你可以以任意顺序重新排列。
请你返回执行以上操作后,在满足前文所述的条件下,arr 中可能的 最大值 。

示例 1:
输入:arr = [2,2,1,2,1]
输出:2
解释:
我们可以重新排列 arr 得到 [1,2,2,2,1] ,该数组满足所有条件。
arr 中最大元素为 2 。
示例 2:
输入:arr = [100,1,1000]
输出:3
解释:
一个可行的方案如下:

  1. 重新排列 arr 得到 [1,100,1000] 。
  2. 将第二个元素减小为 2 。
  3. 将第三个元素减小为 3 。 现在 arr = [1,2,3] ,满足所有条件。 arr 中最大元素为 3 。

示例 3:
输入:arr = [1,2,3,4,5]
输出:5
解释:数组已经满足所有条件,最大元素为 5 。

提示:
1 <= arr.length <= 105
1 <= arr[i] <= 109

题解

#include 
#include 
//#include 
using namespace std;

class Solution {
     
public:
    int maximumElementAfterDecrementingAndRearranging(vector<int>& arr) {
     
        sort(arr.begin(),arr.end());
        if(arr[0] != 1) arr[0] = 1;
        for(int i = 1; i < arr.size(); i++){
     
            if(arr[i] - arr[i -1] > 1) arr[i] = arr[i-1] + 1;
        }
        return arr.back();
    }
};

int main() {
     
    Solution s;
    vector<int> arr = {
     2,2,1,2,1};
    int result = s.maximumElementAfterDecrementingAndRearranging(arr);
    cout << result;
    return 0;
}

5733. 最近的房间

一个酒店里有 n 个房间,这些房间用二维整数数组 rooms 表示,其中 rooms[i] = [roomIdi, sizei] 表示有一个房间号为 roomIdi 的房间且它的面积为 sizei 。每一个房间号 roomIdi 保证是 独一无二 的。

同时给你 k 个查询,用二维数组 queries 表示,其中 queries[j] = [preferredj, minSizej] 。第 j 个查询的答案是满足如下条件的房间 id :

房间的面积 至少 为 minSizej ,且
abs(id - preferredj) 的值 最小 ,其中 abs(x) 是 x 的绝对值。
如果差的绝对值有 相等 的,选择 最小 的 id 。如果 没有满足条件的房间 ,答案为 -1 。

请你返回长度为 k 的数组 answer ,其中 answer[j] 为第 j 个查询的结果。

示例 1:
输入:rooms = [[2,2],[1,2],[3,2]], queries = [[3,1],[3,3],[5,2]]
输出:[3,-1,3]
解释:查询的答案如下:
查询 [3,1] :房间 3 的面积为 2 ,大于等于 1 ,且号码是最接近 3 的,为 abs(3 - 3) = 0 ,所以答案为 3 。
查询 [3,3] :没有房间的面积至少为 3 ,所以答案为 -1 。
查询 [5,2] :房间 3 的面积为 2 ,大于等于 2 ,且号码是最接近 5 的,为 abs(3 - 5) = 2 ,所以答案为 3 。
示例 2:
输入:rooms = [[1,4],[2,3],[3,5],[4,1],[5,2]], queries = [[2,3],[2,4],[2,5]]
输出:[2,1,3]
解释:查询的答案如下:
查询 [2,3] :房间 2 的面积为 3 ,大于等于 3 ,且号码是最接近的,为 abs(2 - 2) = 0 ,所以答案为 2 。
查询 [2,4] :房间 1 和 3 的面积都至少为 4 ,答案为 1 因为它房间编号更小。
查询 [2,5] :房间 3 是唯一面积大于等于 5 的,所以答案为 3 。

提示:
n == rooms.length
1 <= n <= 105
k == queries.length
1 <= k <= 104
1 <= roomIdi, preferredj <= 107
1 <= sizei, minSizej <= 107

题解

#include 
#include 
#include 
#include 
//#include 
#include 
using namespace std;
class Solution4 {
     //5第一名LeetCode@汪乐平
    vector<int> ans;
    set<int> s;
public:
    vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
     
        int n=rooms.size(),q=queries.size(),i,j,k;
        ans.clear();
        ans.resize(q,-1);
        for(i=0;i<n;i++)swap(rooms[i][0],rooms[i][1]);
        sort(rooms.begin(),rooms.end());
        reverse(rooms.begin(),rooms.end());
        for(i=0;i<q;i++)
        {
     
            swap(queries[i][0],queries[i][1]);
            queries[i].push_back(i);
        }
        sort(queries.begin(),queries.end());
        reverse(queries.begin(),queries.end());
        s.clear();
        for(i=j=0;i<q;i++)
        {
     
            k=queries[i][2];
            for(;j<n&&rooms[j][0]>=queries[i][0];j++)s.insert(rooms[j][1]);
            auto it=s.lower_bound(queries[i][1]);
            if(it!=s.end())ans[k]=*it;
            if(it!=s.begin())
            {
     
                it--;
                if(!~ans[k]||ans[k]-queries[i][1]>=queries[i][1]-*it)ans[k]=*it;
            }
        }
        return ans;
    }
};

class Solution4_1 {
     
    vector<int> ans;
    set<int> st;
private:
    static bool cmp(vector<int> &a,vector<int> &b){
     
        return a[1] > b[1];
    }
public:
    vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
     
        int n = rooms.size(), q = queries.size();
        sort(rooms.begin(),rooms.end(),cmp);
        for(int i = 0; i < q; i++) queries[i].push_back(i);
        ans.clear();
        st.clear();
        ans.resize(q,-1);
        sort(queries.begin(),queries.end(),cmp);
        int j = 0;初始化位置很重要
        for(int i = 0; i < q;i++){
     
            int k = queries[i][2];
            j在这初始化会导致超时,因为查询按面积降序排序过,就不需要每次重复从头开始遍历将满足最小查询面积的房间id放进set集合
            for(; j < n && rooms[j][1] >= queries[i][1];j++) st.insert(rooms[j][0]);
            //set.lower_bound(key)会查找第一个键值不小于key的元素的迭代器,否则为st.end()。set.upper_bound(key)会查找第一个比key大的元素的迭代器。
            auto it = st.lower_bound(queries[i][0]);
            if(it != st.end()) ans[k] = *it;
            if(it != st.begin()){
     
                it--;
                int a = ans[k];
                int b = ~a;//-1减去待取反的数即为按位取反的结果:-1-(-1) = 0
                int c = !b;
                if(c || ans[k]-queries[i][0] >= queries[i][0] - *it) ans[k] = *it;
            }

        }
        return ans;
    }
};
class Solution4_2 {
     匿名函数形式写比较函数
    vector<int> ans;
    set<int> st;
private:
    static bool cmp(vector<int> &a,vector<int> &b){
     
        return a[1] > b[1];
    }
public:
    vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
     
        int n = rooms.size(), q = queries.size();
        匿名函数形式写比较函数
        sort(rooms.begin(), rooms.end(), [&](vector<int> & a, vector<int> & b){
     return a[1] > b[1];});
        for (int i = 0; i < q; i++) queries[i].push_back(i);
        ans.clear();
        st.clear();
        ans.resize(q, -1);
        sort(queries.begin(), queries.end(), [&](vector<int> & a, vector<int> & b){
     return a[1] > b[1];});
        int j = 0;初始化位置很重要
        for (int i = 0; i < q; i++) {
     
            int k = queries[i][2];
            //j在这初始化会导致超时,因为查询按面积降序排序过,就不需要每次重复从头开始遍历将满足最小查询面积的房间id放进set集合
            for (; j < n && rooms[j][1] >= queries[i][1]; j++) st.insert(rooms[j][0]);
            //set.lower_bound(key)会查找第一个键值不小于key的元素的迭代器,否则为st.end()。set.upper_bound(key)会查找第一个比key大的元素的迭代器。
            if (!st.empty()) {
     
                int id = INT_MAX;
                int diff = INT_MAX;
                auto pos = st.lower_bound(queries[i][0]);
                if (pos != st.end()) {
     
                    id = *pos;
                    diff = id - queries[i][0];
                }
                if (pos != st.begin()) {
     
                    pos--;
                    if (queries[i][0] - *pos <= diff) id = *pos;
                }
                ans[k] = id;
            }
        }
        return ans;
    }
};
int main() {
     
    Solution4_2 s;
    vector<vector<int>> rooms = {
     {
     2,2},{
     1,2},{
     3,2}};
    vector<vector<int>> queries = {
     {
     3,1},{
     3,3},{
     5,2}};
    vector<int> result = s.closestRoom(rooms,queries);
    for(int i = 0; i < result.size();i++){
     
        cout << result[i] << " ";
    }
    return 0;
}

你可能感兴趣的:(数据结构,算法)