力扣 第 409 场周赛

力扣 第 409 场周赛

前言:

由于力扣的提交方式 和 其他oj类不同 这里c++选手 要先熟悉STL
先会介绍一下会用到特殊语法
1、C++11关键字constexpr

  1. 值不会改变(这一点和普通 const 一样)
  2. 编译期就能得到结果!(普通 const 不一定保证)

2、std::array是具有固定大小的数组。因此,它并不支持添加或删除元素等改变大小的操作。也就是说,当定义一个array时,除了指定元素类型,还要指定容器大小
std::array<T, N> array_name;T 是数组中元素的类型。
N 是数组的大小,必须是一个非负整数。
3、resize() 它将容器的大小修改为指定大小值

 // 创建一个包含 5 个整数的 std::array
  std::array<int, 5> myArray = {1, 2, 3, 4, 5};

4、Lambda表达式
语法格式[capture list] (parameter list) ->return type{function body;};
其中:capture list 为捕获列表; parameter list 为形参列表; return type 为返回值类型(可省略);
简单应用:降序: sort(a.begin(), a.end(), greater<int>()); sort(a.begin(), a.end(), [](int n1, int n2){return n1 > n2;});

3242. 设计相邻元素求和服务

题目描述 :
题目
分析:
这题很简单只要 在不越界的情况下把该元素的上下左右 或 斜上斜下四个元素累加求和就好 由于对他的形式以及c++类知识的欠缺,当世提交的代码如下 不够优雅

class neighborSum {
public:
    int n;
    int grids[10][10];
public:
    neighborSum(vector<vector<int>>& grid) {
          n = grid.size();
        int m = grid[0].size();
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                grids[i][j] = grid[i][j];
                cout << grids[i][j]<< " ";
            }
            cout << endl;
        }
    }
    int get_val(int x, int y){
        return grids[x][y];
    }
  
    int adjacentSum(int value) {
        int sum = 0;
        int x ;
        int y;
        for(int i = 0; i< n; i++){
            for(int j = 0; j < n; j++){
                if(grids[i][j] == value){
                    x = i;
                    y = j;
                    break;
                }
            }
        }
        for(int i = -1; i <= 1; i++){
            for(int j = -1; j <= 1; j++){
                if(!i && !j || abs(i+j) != 1) continue;
                int a = x+i, b = y+j;
                if(a >= 0 && a < n && b >= 0 && b<n){
                    sum += get_val(a,b);
                }
            }
        }
        return sum;
    }
    
    int diagonalSum(int value) {
         int sum = 0;
         int x ;
        int y;
        for(int i = 0; i< n; i++){
            for(int j = 0; j < n; j++){
                if(grids[i][j] == value){
                    x = i;
                    y = j;
                    break;
                }
            }
        }
        for(int i = -1; i <= 1; i++){
            for(int j = -1; j <= 1; j++){
                if(!i || !j) continue;
                int a = x+i, b = y+j;
                if(a >= 0 && a < n && b >= 0 && b<n){
                    sum += get_val(a,b);
                }
            }
        }
        return sum;
    }
};

/**
 * Your neighborSum object will be instantiated and called as such:
 * neighborSum* obj = new neighborSum(grid);
 * int param_1 = obj->adjacentSum(value);
 * int param_2 = obj->diagonalSum(value);
 */

复盘后 参照来源:https://leetcode.cn/problems/design-neighbor-sum-service/solutions/2868968/jian-ji-xie-fa-pythonjavacgo-by-endlessc-ymcf

class neighborSum {
    //存放偏移量 前四個表示上下左右, 後四個表示斜方向的
    static constexpr int dirs[8][2] = {{-1, 0}, {1, 0},  {0, -1},  {0, 1},
    
                                       {1, 1},  {-1, 1}, {-1, -1}, {1, -1}};
    vector<array<int, 2>> s;//保存元素和s[v][0]表示adjacentSum(v) 的结果,s[v][1] 为 diagonalSum(v) 的结果

public:
    neighborSum(vector<vector<int>>& grid) {
        int n = grid.size();
        s.resize(n * n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int v = grid[i][j];
                for (int k = 0; k < 8; k++) {
                    int x = i + dirs[k][0], y = j + dirs[k][1];
                    if (0 <= x && x < n && 0 <= y && y < n) {
                        s[v][k / 4] += grid[x][y];
                    }
                }
            }
        }
    }

    int adjacentSum(int value) { return s[value][0]; }

    int diagonalSum(int value) { return s[value][1]; }
};

/**
 * Your neighborSum object will be instantiated and called as such:
 * neighborSum* obj = new neighborSum(grid);
 * int param_1 = obj->adjacentSum(value);
 * int param_2 = obj->diagonalSum(value);
 */

3243. 新增道路查询后的最短距离 I

题目描述 :
question

分析: BFS暴力 每次加完边 跑一遍BFS
初始化后 g 数组:
初始g数组
对映情况 这时从0到4 要走vis[5-1] = 4 步
在这里插入图片描述
当加一条边
在这里插入图片描述
此时 g 数组变为
在这里插入图片描述
这样 访问g[2]时 会把vis[4]修改为 0 + 1 + 1 + 1 = 3 返回结果3

class Solution {
public:
    vector<int> shortestDistanceAfterQueries(int n,
                                             vector<vector<int>>& queries) {
        vector<int> g[n];
        // 初始化
        for (int i = 1; i < n; i++)
            g[i - 1].push_back(i);

        auto bfs = [&]() {
            int vis[n];
            memset(vis, -1, sizeof vis);
            queue<int> q;
            q.push(0);
            vis[0] = 0;

            while (q.size()) {
                auto tmp = q.front();
                q.pop();
                for (auto k : g[tmp]) {
                    if (vis[k] == -1) {
                        q.push(k);
                        vis[k] = vis[tmp] + 1;
                    }
                }
            }
            return vis[n - 1];
        };

        vector<int> ans;
        for (auto& qry : queries) {
            g[qry[0]].push_back(qry[1]);
            ans.push_back(bfs());
        }
        return ans;
    }
};

3244. 新增道路查询后的最短距离 II

题目描述 :
添加链接描述**
分析: 利用并查集 存的是每条边

class Solution {
public:
    vector<int> shortestDistanceAfterQueries(int n,
                                             vector<vector<int>>& queries) {
        vector<int> fa(n - 1);
        iota(fa.begin(), fa.end(), 0);
        auto find = [&](int x) {
            int rt = x;
            while (rt != fa[rt]) {
                rt = fa[rt];
            }
            while (fa[x] != rt) {
                int tmp = fa[x];
                fa[x] = rt;
                x = tmp;
            }
            return rt;
        };
        vector<int> ans(queries.size());
        int cnt = n - 1;
        for (int i = 0; i < queries.size(); i++) {
            int l = queries[i][0], r = queries[i][1] - 1;
            int fr = find(r);
            for (int j = find(l); j < r; j = find(j + 1)) {
                fa[j] = fr;
                cnt--;
            }
            ans[i] = cnt;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值