leetcode周赛238-题解

A.K进制各位数字总和

签到题,直接模k转化即可
(py代码)

class Solution:
    def sumBase(self, n: int, k: int) -> int:
        sum = 0
        while n > 0:
            sum += n % k
            n //= k
        return sum

B.最高元素频数

排序后考虑所有区间右端点,求出能全部数值改成右端点数值的左端点的最小值
显然随着右端点的增加左端点也只会增加不会减小,所以直接维护即可
c++注意开ll,会爆int

typedef long long ll;
class Solution
{
public:
    int maxFrequency(vector<int> &nums, int k)
    {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        ll suml = 0;
        int le = 0;
        int res = 1;
        for (int ri = 1; ri < n; ri++)
        {
            suml += (ll)(ri - le) * (nums[ri] - nums[ri - 1]);
            while (suml > k)
            {
                suml -= (nums[ri] - nums[le]);
                le++;
            }
            res = max(res, ri - le + 1);
        }
        return res;
    }
};

C.元音顺序最长子串

直接维护当前到达第几个元音,暴力扫一遍即可

int getid(char c)
{
    switch (c)
    {
    case 'a':
        return 0;
    case 'e':
        return 1;
    case 'i':
        return 2;
    case 'o':
        return 3;
    case 'u':
        return 4;
    default:
        return -1;
    }
}
int id[500001];
class Solution
{
public:
    int longestBeautifulSubstring(string word)
    {
        int i = 0, j = 0;
        int n = word.length();
        for (int i = 0; i < n; i++)
            id[i] = getid(word[i]);
        int res = 0;
        while (i < n)
        {
            while (id[i] != 0)
                i++;
            j = i;
            int cid = 0;
            while (j < n && id[j] <= cid + 1 && id[j] >= cid)
            {
                cid = id[j];
                j++;
            }
            if (cid == 4)
                res = max(res, j - i);
            i = j;
        }
        return res;
    }
};

D.最高建筑高度

先添加(1,0)和(n,n-1)限制(在没给n限制才添加n-1)
然后按id排序所有限制
设u位置的限制为 l i m u lim_u limu
对于一个位置x,考虑其左边的限制对x的影响为 m i n l ≤ x ( x − l + l i m l ) min_{l\leq x}(x-l+lim_l) minlx(xl+liml)
右边限制对x的影响为 m i n r ≥ x ( r + l i m r − x ) min_{r\geq x}(r+lim_r-x) minrx(r+limrx)
对左边维护 l i m x − x lim_x-x limxx的前缀最小值 s l sl sl,右边维护 l i m x + x lim_x+x limx+x的后缀最小值 s r sr sr
然后考虑两个相邻限制位置 l e , r i le,ri le,ri,对应下标 i , i + 1 i,i+1 i,i+1
然后考虑左边的限制和右边的限制,可以发现左边限制为 s l i + x sl_i +x sli+x,右边为 s r i + 1 − x sr_{i+1}-x sri+1x,令这两个最小值最大的 x = ( s r i + 1 − s l i ) / 2 x=(sr_{i+1}-sl_{i})/2 x=(sri+1sli)/2
x 在 l e 与 r i 之 间 时 直 接 取 x 位 置 的 最 大 值 记 录 答 案 x在le与ri之间时直接取x位置的最大值记录答案 xlerix
x 在 l e 左 侧 时 取 l e 的 答 案 x在le左侧时取le的答案 xlele
x 在 r i 右 侧 时 取 r i 答 案 x在ri右侧时取ri答案 xriri
代码(py)

class Solution:
    def maxBuilding(self, n: int, restrictions: list) -> int:
        restrictions.sort(key=lambda x: x[0])
        restrictions = [[1, 0]]+restrictions
        cnt = len(restrictions)
        if(restrictions[cnt-1][0] != n):
            restrictions += [[n, n-1]]
            cnt += 1
        sl = [n]*cnt
        sr = [n*2]*cnt
        for i in range(cnt):
            sl[i] = min(sl[i], restrictions[i][1]-restrictions[i][0])
            if(i > 0):
                sl[i] = min(sl[i], sl[i-1])
        for i in range(cnt-1, -1, -1):
            sr[i] = min(sr[i], restrictions[i][1]+restrictions[i][0])
            if(i != cnt-1):
                sr[i] = min(sr[i], sr[i+1])
        ans = 0
        for i in range(cnt-1):
            le = restrictions[i][0]
            ri = restrictions[i+1][0]
            mx = (sr[i+1]-sl[i])//2
            if(mx <= le):
                ans = max(ans, min(sl[i]+le, sr[i+1]-le))
            elif mx >= ri:
                ans = max(ans, min(sl[i]+ri, sr[i+1]-ri))
            else:
                ans = max(ans, min(mx+sl[i], sr[i+1]-mx))
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值