第 51 场双周赛

  1. 将所有数字用字符替换
/**
 * @param {string} s
 * @return {string}
 */
var replaceDigits = function(s) {
    let arr = s.split("");
    for(let i=1;i<arr.length;i+=2) {
        arr[i] = String.fromCharCode(arr[i-1].charCodeAt(0) + +arr[i]);
    }  
    return arr.join("");
};

  1. 座位预约管理系统
/**
 * @param {number} n
 */
var SeatManager = function(n) {
    this.arr = new Array(n).fill(0);
    this.left = 0;
    this.right = 1;
};

/**
 * @return {number}
 */
SeatManager.prototype.reserve = function() {
    let res = this.left + 1;
    this.arr[this.left] = 1;
    this.left = this.right;
    this.right++;
    if(this.arr[this.right] === 1) {
        while(this.arr[this.right] === 1) {this.right++;}
    }
    return res;
};

/** 
 * @param {number} seatNumber
 * @return {void}
 */
SeatManager.prototype.unreserve = function(seatNumber) {
    seatNumber = seatNumber - 1;
    if(seatNumber < this.left) {
        this.right = this.left;
        this.left = seatNumber;
    }
    else if(seatNumber>this.left && seatNumber<this.right) {
        this.right = seatNumber;
    }
    
    this.arr[seatNumber] = 0;
};

/**
 * Your SeatManager object will be instantiated and called as such:
 * var obj = new SeatManager(n)
 * var param_1 = obj.reserve()
 * obj.unreserve(seatNumber)
 */
  1. 减小和重新排列数组后的最大元素
/**
 * @param {number[]} arr
 * @return {number}
 */
var maximumElementAfterDecrementingAndRearranging = function(arr) {
    if(arr.length === 1) return 1;
    arr.sort((a,b) => a-b);
    
    if(arr[0] !== 1) arr[0] = 1;
    for(let i=1;i<arr.length;i++) {
        if(arr[i] > arr[i-1]+1) arr[i] = arr[i-1] + 1;
    }
    return arr[arr.length-1];
};
  1. 最近的房间
    看错题目了,还没A出来,题解参考他人:
struct Block {
    // block 中最小的房间 size
    int min_size = INT_MAX;
    // block 中的房间 id
    vector<int> ids;
    // 原始数据
    vector<pair<int, int>> origin;

    Block() = default;

    // 加入一个房间
    void insert(int id, int size) {
        origin.emplace_back(id, size);
        ids.push_back(id);
        min_size = min(min_size, size);
    }

    // 添加完所有房间后,将房间 id 排序,便于后续二分
    void sort() {
        ::sort(ids.begin(), ids.end());
    }

    // 封装一下二分函数,找最小的大于等于它的
    int geq(int preferred) {
        auto it = lower_bound(ids.begin(), ids.end(), preferred);
        return it == ids.end() ? -1 : *it;
    }

    // 封装一下二分函数,找最大的严格小于它的
    int lt(int preferred) {
        auto it = upper_bound(ids.begin(), ids.end(), preferred);
        return it == ids.begin() ? -1 : *prev(it);
    }
};

class Solution {
private:
    static constexpr int BLOCK_SIZE = 300;

public:
    vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
        int n = rooms.size();
        int q = queries.size();

        // 按照 size 升序排序
        sort(rooms.begin(), rooms.end(), [](const auto& r1, const auto& r2) { return r1[1] < r2[1]; });

        // 每 BLOCK_SIZE 个房间放进一个 block
        vector<Block> blocks;
        for (int i = 0; i < n; ++i) {
            if (i % BLOCK_SIZE == 0) {
                blocks.emplace_back();
            }
            blocks.back().insert(rooms[i][0], rooms[i][1]);
        }
        for (auto&& block: blocks) {
            block.sort();
        }

        vector<int> ans(q, -1);
        for (int i = 0; i < q; ++i) {
            int preferred = queries[i][0];
            int minsize = queries[i][1];
            int mindiff = INT_MAX;
            for (auto it_block = blocks.rbegin(); it_block != blocks.rend(); ++it_block) {
                auto&& block = *it_block;
                // block 中最小 size 的房间大于等于 minsize,整个 block 都可以选择
                if (block.origin[0].second >= minsize) {
                    int c1 = block.geq(preferred);
                    if (c1 != -1 && c1 - preferred < mindiff) {
                        mindiff = c1 - preferred;
                        ans[i] = c1;
                    }
                    int c2 = block.lt(preferred);
                    if (c2 != -1 && preferred - c2 <= mindiff) {
                        mindiff = preferred - c2;
                        ans[i] = c2;
                    }
                }
                else {
                    // 只有部分都可以选择,遍历一下所有的房间
                    auto&& rooms = block.origin;
                    for (auto it_room = rooms.rbegin(); it_room != rooms.rend(); ++it_room) {
                        if (it_room->second >= minsize) {
                            int diff = abs(it_room->first - preferred);
                            if (diff < mindiff || (diff == mindiff && it_room->first < ans[i])) {
                                mindiff = diff;
                                ans[i] = it_room->first;
                            }
                        }
                        else {
                            break;
                        }
                    }
                    // 再之前的 block 一定都严格小于 minsize,可以直接退出
                    break;
                }
            }
        }
        return ans;
    }
};

作者:zerotrac2
链接:https://leetcode-cn.com/problems/closest-room/solution/ni-yong-yuan-ke-yi-xiang-xin-fen-kuai-su-88a4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值