Leetcode 第162场周赛

地址

https://leetcode-cn.com/contest/weekly-contest-162

吐槽一下

太久没写C++感觉都不会写了,很多语法都不熟悉,其实4题都是暴力都能做的但是由于时间不够居然没做完😔

题目

5255. 奇数值单元格的数目

题意:

给你一个 n 行 m 列的矩阵,最开始的时候,每个单元格中的值都是 0。

另有一个索引数组 indices,indices[i] = [ri, ci] 中的 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。

你需要将每对 [ri, ci] 指定的行和列上的所有单元格的值加 1。

请你在执行完所有 indices 指定的增量操作后,返回矩阵中 「奇数值单元格」 的数目。

思路:

直接模拟就好了

class Solution {
public:
    int oddCells(int n, int m, vector<vector<int>>& indices) {
        vector<vector<int>> matrix;

        for (int i = 0; i < n; i++){
            vector<int> aRow;
            for(int j = 0; j < m; j++){
                aRow.push_back(0);
            }
            matrix.push_back(aRow);
        }

        for(int i = 0; i < indices.size(); i++){
            int row = indices[i][0];
            int col = indices[i][1];
            for(int j = 0; j < m; j++){
                matrix[row][j]++;
            }
            for(int j = 0; j < n; j++){
                matrix[j][col]++;
            }
        }
        
        int res = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if (matrix[i][j] % 2 == 1){
                    res++;
                }
            }
        }
        return res;
    }
};

5256. 重构 2 行二进制矩阵

题意:

给你一个 2 行 n 列的二进制数组:

矩阵是一个二进制矩阵,这意味着矩阵中的每个元素不是 0 就是 1。
第 0 行的元素之和为 upper。
第 1 行的元素之和为 lower。
第 i 列(从 0 开始编号)的元素之和为 colsum[i],colsum 是一个长度为 n 的整数数组。
你需要利用 upper,lower 和 colsum 来重构这个矩阵,并以二维整数数组的形式返回它。

如果有多个不同的答案,那么任意一个都可以通过本题。

如果不存在符合要求的答案,就请返回一个空的二维数组。

思路:

  • 只有2行,那么colsum元素为0的不填,2的上下都填
  • 只需考虑colsum元素1的时候怎么填
  • 先把2的填完,然后填1的先填第一行,第一行填满了后填第二行
  • 填完后判断一下是不是和upper、lower数量相同其实就好了
class Solution {
public:

    vector<vector<int>> reconstructMatrix(int upper, int lower, vector<int>& colsum) {
        vector<vector<int>> matrix;
        int sum = 0;
        for(int i = 0; i < colsum.size(); i++){
            sum += colsum[i];
        }
        if(sum != upper + lower){
            return matrix;
        }

        
        int size = colsum.size();
        vector<int> up(size, 0);
        vector<int> down(size, 0);
        matrix.push_back(up);
        matrix.push_back(down);
        int cntUp = 0;
        for(int i = 0; i < colsum.size(); i++){
            if(colsum[i] == 2){
                matrix[0][i] = 1;
                matrix[1][i] = 1;
                cntUp++;
            }

        }
        for(int i = 0; i < colsum.size(); i++){
            if(colsum[i] == 1){
                if (cntUp < upper){
                    matrix[0][i] = 1;
                    cntUp++;
                }else{
                    matrix[1][i] = 1;
                }
            }
        }
        int sumUp = 0, sumLow = 0;
        for(int i = 0; i < colsum.size(); i++){
            sumUp += matrix[0][i];
            sumLow += matrix[1][i];

        }
        if(sumUp != upper || sumLow != lower){
            vector<vector<int>> matrix2;
            return matrix2;
        }

        return matrix;
        
    }
};

5257. 统计封闭岛屿的数目

题意:

有一个二维矩阵 grid ,每个位置要么是陆地(记号为 0 )要么是水域(记号为 1 )。

我们从一块陆地出发,每次可以往上下左右 4 个方向相邻区域走,能走到的所有陆地区域,我们将其称为一座「岛屿」。

如果一座岛屿 完全 由水域包围,即陆地边缘上下左右所有相邻区域都是水域,那么我们将其称为 「封闭岛屿」。

请返回封闭岛屿的数目。

思路:

直接暴力dfs或bfs搜就可以了。注意遇到边界就不算是孤岛了

class Solution {
public:
    int idir[4] = {0, 1, 0, -1};
    int jdir[4] = {1, 0, -1, 0};
    
    bool dfs(int i, int j, vector<vector<int>>& grid, vector<vector<int>>& visited, int label, int n, int m){
        visited[i][j] = label;
        bool reachBorder = false;
        for(int t = 0; t < 4; t++){
            int nexti = i + idir[t];
            int nextj = j + jdir[t];
            if(nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && grid[nexti][nextj] == 0 && visited[nexti][nextj] == 0){
                if(dfs(nexti, nextj, grid, visited, label, n, m)){
                    reachBorder = true;
                }
            }
            if(nexti < 0 || nexti >= n || nextj < 0 || nextj >= m){
                reachBorder = true;
            }
        }
        
        return reachBorder;
    }
    
    int closedIsland(vector<vector<int>>& grid) {
        vector<vector<int>> visited;
        for(int i = 0; i < grid.size(); i++){
            vector<int> aRow;
            visited.push_back(aRow);
            for(int j = 0; j < grid[i].size(); j++){
                visited[i].push_back(0);
            }
        }
        int res = 0;
        int label = 1;
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[i].size(); j++){
                if(visited[i][j] == 0 && grid[i][j] == 0){
                    bool searchRes = dfs(i, j, grid, visited, label, grid.size(), grid[i].size());
                    label++;
                    if(searchRes == false){
                        res++;
                    }
                }
            }
        }
        return res;
    }
};

5258. 得分最高的单词集合

题意:

你将会得到一份单词表 words,一个字母表 letters (可能会有重复字母),以及每个字母对应的得分情况表 score。

请你帮忙计算玩家在单词拼写游戏中所能获得的「最高得分」:能够由 letters 里的字母拼写出的 任意 属于 words 单词子集中,分数最高的单词集合的得分。

单词拼写游戏的规则概述如下:

玩家需要用字母表 letters 里的字母来拼写单词表 words 中的单词。
可以只使用字母表 letters 中的部分字母,但是每个字母最多被使用一次。
单词表 words 中每个单词只能计分(使用)一次。
根据字母得分情况表score,字母 ‘a’, ‘b’, ‘c’, … , ‘z’ 对应的得分分别为 score[0], score[1], …, score[25]。
本场游戏的「得分」是指:玩家所拼写出的单词集合里包含的所有字母的得分之和。

思路:

  • 扯了那么多,反正最后都是靠word单词计分,而且每个单词只计一次,那么枚举单词的所有子集,判断一下每个子集是不是可以由letter里的字符构成就可以了。
class Solution {
public:
    int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
        int res = 0;
        map<string, int> mpWordScore;
        for(auto &word : words){
            int wordScore = 0;
            for(int i = 0; i < word.length(); i++){
                wordScore += score[word[i] - 'a'];
            }
            mpWordScore[word] = wordScore;
        }
        
        for(int n = 1; n < 1 << words.size(); n++){
            int nBite = n, i = 0;
            vector <string> selectWords;
            while(nBite > 0){
                if (nBite % 2 == 1){
                    selectWords.push_back(words[i]);
                }
                nBite /= 2;
                i++;
            }
            map<char, int> cntNeedLetter;
            int aScore = 0;
            for(auto &word : selectWords){
                aScore += mpWordScore[word];
                for(auto &ch : word){
                    if(cntNeedLetter.count(ch) > 0){
                        cntNeedLetter[ch]++;
                    }else{
                        cntNeedLetter[ch] = 1;
                    }
                }
            }
            
            bool canBuild = true;
            for (const auto& kv : cntNeedLetter){
                char ch = kv.first;
                int cnt = kv.second;
                for(auto &ch2: letters){
                    if(ch == ch2){
                        cnt--;
                    }
                }
                if(cnt > 0){
                    canBuild = false;
                }
            }
            
            if(canBuild == true){
                res = max(res, aScore);
            }
            selectWords.clear();
        }
        
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值