Leetcode周赛踩坑总结

前言

每次竞赛总会找到一些细小的,以前没见过的错误,或者想到一些还不错的解法,于是通通记录在这。
毕竟有的错会导致WA,相当于直接多做了5分钟,还是很不划算的。


第348场竞赛

P3查询后矩阵的和

这题的难点是要想到逆序处理。思路是从后往前覆盖,已经处理过的行或列就不用再重复处理。我当时的想法是用哈希表记录对应的一组操作,来让其不会重复

使用类型:unordered_set<pair<int, int>>
pair记录对应的 type 和操作的行号或列号
可这里的坑在于 pair 需要自定义哈希函数,pair 没有默认定义的哈希函数。
哈希函数的指定只需让其每一个元素唯一即可,这道题的数据是 1e4,所以据此构造出哈希函数。

struct pair_hash {
        template<class T1, class T2>
        size_t operator()(const pair<T1, T2> &data) const {
            return data.first * 1e4 + data.second;
        }
    };
class Solution {
public:
    long long matrixSumQueries(int n, vector<vector<int>>& queries) {
        unordered_set<pair<int, int>, pair_hash> operations;
        vector<int> record;
        int i, m = queries.size();
        for (i = m - 1; i >= 0; --i) {
            if (operations.count({queries[i][0], queries[i][1]}) == 0) {
                operations.insert({queries[i][0], queries[i][1]});
                record.emplace_back(i);
            }
        }
        // operations 过滤重复操作
        // record 记录过滤后的操作
        // 并且 record 的前面对应的是 queries 里后面的操作
        int j;
        long long ans = 0;
        int row = n, colone = n;
        // row 和 colone 记录剩余的未填的行或列
        for (j = 0; j < record.size(); ++j) {
            if (row > 0 && queries[record[j]][0] == 0) {
            	// 还有多少剩余的列可以填上这个数
                ans += colone * queries[record[j]][2];
                --row;
            } else if (colone > 0 && queries[record[j]][0] == 1) {
            	// 还有多少剩余的行可以填上这个数
                ans += row * queries[record[j]][2];
                --colone;
            }
        }
        return ans;
    }
};

第349场竞赛

  1. long 的最大值:LONG_MAX
  2. longlong 的最大值: LLONG_MAX
  3. int 和 long long 在做乘法的时候乘数在int范围内,如果乘积超了int,也需要将乘数定义为long long

P3收集巧克力
这题的想法是遍历执行操作的次数,从 1 到 n
注意复杂度 n 仅 1 0 3 10^3 103
使用二维数组记录下当前位置经过 k 次操作后的最小值

pool[i][k] 即表示经过 k 次操作 下标 i 位置上的最小值,随后我们遍历所有次数计算值即可

class Solution {
public:
    long long minCost(vector<int>& nums, int x) {
        int i, j, n = nums.size();
        vector<vector<int>> pool(n, vector<int>(n));
        for (i = 0; i < n; ++i) {
            int mmin = nums[i];
            int k = 0;
            pool[i][k] = nums[i];
            for (j = i - 1; j >= 0; --j) {
                pool[i][++k] = mmin = min(mmin, nums[j]);
                //cout << pool[i][k] << " ";
            }
            for (j = n - 1; j > i; --j) {
                pool[i][++k] = mmin = min(mmin, nums[j]);
                //cout << pool[i][k] << " ";
            }
            //cout << endl;
        }
        long long res = LLONG_MAX;
        for (i = 0; i < n; ++i) {
        	// 使用 i 次操作带来的成本 i * x
            long long ans = (long long)i * x;
            for (j = 0; j < n; ++j) {
            	// 加上每个位置上 i 次操作对应的最小值
                ans += pool[j][i];
            }
            res = min(res, ans);
        }
        return res;
    }
};

这题的难点在于想到对次数进行遍历,从直觉上来说其代价似乎较为高昂,然而借用二维数组,时间复杂度控制在了 1 0 6 10^6 106量级


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值