Leetcode周赛367总结

Q1 找出满足差值条件的下标I

  • 题目链接

  • 解题思路:

    • 数据范围很小,可以直接枚举两个下标,计算是否满足条件,如果满足条件直接返回对应下标
    • 如果检查了所有下标都不满足条件,返回[-1,-1]
  • 解题代码:

class Solution {
public:
    vector<int> findIndices(vector<int>& nums, int indexDifference, int valueDifference) {
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            for(int j = i; j < n; j++)
            {
                if(abs(i - j) >= indexDifference && abs(nums[i] - nums[j]) >= valueDifference)
                    return {i, j};
            }
        }
        return {-1, -1};
    }
};

Q2 最短且字典序最小的美丽子字符串

  • 题目链接

  • 解题思路:

    • 数据范围仍然很小
    • 可以直接O(n^2)复杂度暴力枚举所有子字符串,判断其是否为最短的且字典序最小的美丽子字符串
  • 解题代码

class Solution {
public:
    string shortestBeautifulSubstring(string s, int k) {
        int n = s.size();
        string ans;
        int ansLen = INT_MAX;
        for(int i = 0; i < n; i++)
        {
            int cnt = 0;
            string temp;
            for(int j = i; j < n; j++)
            {
                if(s[j] == '1')
                    cnt += 1;
                temp += s[j];
                if(cnt == k)
                {
                    if(temp.size() < ansLen || (temp.size() == ansLen && temp < ans))
                    {
                        ans = temp;
                        ansLen = temp.size();
                    }
                    break;
                }
            }
        }
        return ans;
    }
};

  • 解题思路2:

    • 可以用滑动窗口
    • 窗口中始终维护包含k个1的子字符串
    • 右指针一直右移,当窗口中1的个数大于k或左指针指向0时,左指针右移
  • 解题代码:


class Solution {
public:
    string shortestBeautifulSubstring(string s, int k) {
        int cnt = 0;
        for(auto ch : s)
            cnt += (ch == '1');
        if(cnt < k)
            return "";
       
        string ans = s;
        int n = s.size();
        int l = 0;
        int cnt1 = 0;
        for(int r = 0; r < n; r++)
        {
            cnt1 += (s[r] == '1');
            while(cnt1 > k || s[l] == '0')
            {
                cnt1 -= (s[l] == '1');
                l += 1;
            }
            if(cnt1 == k)
            {
                string temp = s.substr(l, r-l+1);
                if(temp.size() < ans.size() || temp.size() == ans.size() && temp < ans)
                    ans = temp;
            }
        }
        return ans;
    }
};


Q3 找出满足差值条件的下标II

  • 题目链接

  • 解题思路:

    • 从前向后遍历每一个下标
    • 维护[0, max(0, i-indexDifference)]范围内的最大值、最小值及其下标
    • 如果存在abs(最大值 - nums[i]) 或 abs(最小值 - nums[i]) 大于等于valueDifference,返回对应下标
    • 如果不存在满足条件的下标,返回[-1, -1]
  • 解题代码:


class Solution {
public:
    vector<int> findIndices(vector<int>& nums, int indexDifference, int valueDifference) {
        int mx = INT_MIN, mn = INT_MAX;
        int mxIdx = -1, mnIdx = -1;
        int n = nums.size();
        for(int i = indexDifference; i < n; i++)
        {
            if(nums[i-indexDifference] > mx)
            {
                mx = nums[i-indexDifference];
                mxIdx = i - indexDifference;
            }
            if(nums[i-indexDifference] < mn)
            {
                mn = nums[i-indexDifference];
                mnIdx = i - indexDifference;
            }
            if(abs(mx - nums[i]) >= valueDifference)
                return {mxIdx, i};
            if(abs(mn - nums[i]) >= valueDifference)
                return {mnIdx, i};
        }
        return {-1, -1};
    }
};


赛后复盘可以只维护最大值和最小值的下标,不用同时维护最大值和最小值

Q4 前后缀分解

  • 题目链接

  • 解题思路:

    • 将二维数组展成一维矩阵
    • 问题就变成了求每一个位置前缀与后缀的乘积
    • 前后缀分解即可
  • 解题代码:


class Solution {
public:
    vector<vector<int>> constructProductMatrix(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        vector<long long> left(n*m, 1), right(n*m, 1);
        for(int i = 1; i < n*m; i++)
        {
            int x = (i-1) / m;
            int y = (i-1) % m;
            left[i] = (left[i-1] * grid[x][y]) % 12345;
        }
        for(int i = n*m-2; i >= 0; i--)
        {
            int x = (i+1) / m;
            int y = (i+1) % m;
            right[i] = (right[i+1] * grid[x][y]) % 12345;
        }
        vector<vector<int>> ans(n, vector<int>(m, 0));
        for(int i = 0; i < n*m; i++)
        {
            int x = i / m;
            int y = i % m;
            ans[x][y] = (left[i] * right[i]) % 12345;
        }
        return ans;
    }
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值