LeetCode---394周赛

news2024/11/17 12:19:48

题目列表

3120. 统计特殊字母的数量 I

3121. 统计特殊字母的数量 II

3122. 使矩阵满足条件的最少操作次数

3123. 最短路径中的边

一、统计特殊字母的数量I

分别统计小写字母和大写字母是否出现,然后求交集即可,这里我们可以用数组统计,但其实没必要,一共就26个字母,我们可以用26个bit位的0/1来表示字符是否存在,由于区分大小写,所以我们共需要两个int变量就行,代码如下

class Solution {
public:
    int numberOfSpecialChars(string word) {
        int cnt[2]={0};
        for(auto e:word){
            if((e>>5)&1) cnt[0] |= 1<<(e-'a'); // 小写字母的二进制表示的第5位为1,大写字母为0
            else cnt[1] |= 1<<(e-'A');
        }
        return __builtin_popcount(cnt[0]&cnt[1]);
    }
};

二、统计特殊字母的数量II

 

这题和第一题的区别是限定了大小写字母的位置关系,即小写字母必须在其对应的大写字母的前面,这个其实也很容易,我们只要统计不同小写字母出现的最靠后的位置和不同大写字母出现的最靠前的位置,来看对应的大小写字母是否符合条件即可,代码如下

class Solution {
public:
    int numberOfSpecialChars(string word) {
        int n = word.size();
        vector<int>first(26,-1);//记录大写字母出现最靠前的位置
        vector<int>last(26,-1);//记录小写字母出现最靠后的位置
        for(int i=0;i<n;i++){
            char c = word[i];
            if((c>>5)&1) last[c-'a']=i;
            else {
                if(first[c-'A']==-1) 
                    first[c-'A']=i;
            }
        }
        int ans = 0;
        for(int i=0;i<26;i++){
            if(first[i]<0||last[i]<0) continue;
            ans += first[i]>last[i];
        }
        return ans;
    }
};

能不能改为一次遍历呢???实际上是否满足条件符合下面这样一个状态转换关系

代码如下

class Solution {
public:
    int numberOfSpecialChars(string word) {
        int n = word.size(),cnt = 0;
        vector<int>status(26);
        for(auto e:word){ // 边进行状态转化,边统计符合条件的字母个数
            if((e>>5)&1){
                int i = e - 'a';
                if(status[i]==0) status[i]=1;
                else if(status[i]==2) status[i]=-1,cnt--;
            }else{
                int i = e - 'A';
                if(status[i]==0) status[i]=-1;
                else if(status[i]==1) status[i]=2,cnt++;
            }
        }
        return cnt;
    }
};

三、使矩阵满足条件的最少操作次数

根据题目条件, 我们知道符合条件的矩阵满足,每一列的元素都相同且相邻列的元素不同,也就是说,我们只关心每一列的元素情况,所以我们可以先统计每一列中的0-9出现的次数。题目要求最少操作次数,也就是我们最多能让多少个元素保持不变,由此我们设计出如下的状态定义:

f[i][j]表示前i列中,第i列元素为j时,最多能有多少个元素保持不变

状态转移方程:f[i+1][j] = max(f[i][k])+cnt[i][j],0<=k<=9&&k!=j

初始化:f[0][j] = 0,前0列没有元素,最多保留0个元素不变

代码如下

class Solution {
public:
    int minimumOperations(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> cnt(m,vector<int>(10));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                cnt[i][grid[j][i]]++;
            }
        }
        vector<vector<int>> dp(m+1,vector<int>(10));
        // dp[i][j] 表示当前位置为j且前i列符合条件的不需要改变的最大元素个数
        // dp[i][j] = max(dp[i-1][k]) + cnt[i][j] k!=j 0-9
        for(int i=0;i<m;i++){
            for(int j=0;j<10;j++){
                int mx = INT_MIN;
                for(int k=0;k<10;k++){
                    if(k==j) continue;
                    mx = max(mx,dp[i][k]);
                }
                dp[i+1][j]=mx + cnt[i][j];
            }
        }
        return n*m-*max_element(dp.back().begin(),dp.back().end());
    }
};

// 空间优化
class Solution {
public:
    int minimumOperations(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> cnt(m,vector<int>(10));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                cnt[i][grid[j][i]]++;
            }
        }
        vector<int>f(10);
        for(int i=0;i<m;i++){
            vector<int>tmp(10);
            for(int j=0;j<10;j++){
                int mx = INT_MIN;
                for(int k=0;k<10;k++){
                    if(k==j) continue;
                    mx = max(mx,f[k]);
                }
                tmp[j]=mx + cnt[i][j];
            }
            f=tmp;
        }
        return n*m-*max_element(f.begin(),f.end());
    }
};

通过上述的状态定义,我们知道这题本质就是在求当前选择0-9中的几时,保留下来的数最多,由于相邻的列元素不同这一条件,其实我们只要维护前i-1列中保留下来的数的最大值和次大值即可,只有这两个值才会对第i列的状态最值产生影响【类似于我们如果只求数组中的最大值,就没必要将整个数组排序,只要遍历一边即可】,代码如下

class Solution {
public:
    int minimumOperations(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> cnt(m,vector<int>(10));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                cnt[i][grid[j][i]]++;
            }
        }
        int f0 = 0, f1 = 0;
        int pre = -1;
        for(int i=0;i<m;i++){
            int mx = 0, mx2 = 0, x;
            for(int j=0;j<10;j++){
                int res = (j==pre?f1:f0) + cnt[i][j];
                if(res > mx) mx2 = mx, mx = res, x = j;
                else if(res > mx2) mx2 = res;
            }
            f0 = mx, f1 = mx2, pre = x;
        }
        return n*m-f0;
    }
};

四、最短路径中的边

这题就是找最短路径经过的边,本质还是求最短路径(用Dijkstra算法),只不过需要从最短路径逆推出它可能经过的边,代码如下

class Solution {
public:
    vector<bool> findAnswer(int n, vector<vector<int>>& edges) {
        vector<vector<tuple<int,int,int>>> g(n);
        int m = edges.size();
        for(int i=0;i<m;i++){
            auto e = edges[i];
            int x = e[0], y = e[1], w = e[2];
            g[x].emplace_back(y,w,i);
            g[y].emplace_back(x,w,i);
        }

        vector<long long>dist(n,LLONG_MAX);
        dist[0] = 0;
        priority_queue<pair<long long,int>> pq; // [d,i]
        pq.emplace(0,0);
        while(pq.size()){
            auto [d,i] = pq.top(); pq.pop();
            if(-d!=dist[i]) continue;
            for(auto [y,w,_]:g[i]){
                if(dist[y]>dist[i]+w){
                    dist[y] = dist[i]+w;
                    pq.emplace(-dist[y],y);
                }
            }
        }
        vector<bool> ans(m);
        if(dist[n-1]==LLONG_MAX)
            return ans;
        
        vector<bool> vis(n);
        function<void(int)>dfs=[&](int x){
            vis[x] = true;
            for(auto[y,w,i]:g[x]){
                if(dist[y]+w!=dist[x])
                    continue;
                ans[i] = true;
                if(!vis[y]) dfs(y);
            }
        };
        dfs(n-1);
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PotatoPie 4.0 实验教程(30) —— FPGA实现摄像头图像中值滤波

中值滤波是什么&#xff1f; 图像的中值滤波是一种非线性图像滤波方法&#xff0c;它用于去除图像中的椒盐噪声或其他类型的噪声。中值滤波的原理是用每个像素周围的邻域中的中值来替代该像素的值。与均值滤波不同&#xff0c;中值滤波不会受到极端值的影响&#xff0c;因此在处…

pytest教程-27-分布式执行用例插件-pytest-xdist

上一小节我们学习了pytest随机执行用例插件-pytest-random-order&#xff0c;本小节我们讲解一下pytest分布式执行用例插件pytest-xdist。 前言 平常我们手工测试用例非常多时&#xff0c;比如有1千条用例&#xff0c;假设每个用例执行需要1分钟。如果一个测试人员执行需要10…

Bert基础(十八)--Bert实战:NER命名实体识别

1、命名实体识别介绍 1.1 简介 命名实体识别&#xff08;NER&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一项关键技术&#xff0c;它的目标是从文本中识别出具有特定意义或指代性强的实体&#xff0c;并对这些实体进行分类。这些实体通常包括人名、地名、组织…

【Linux】make 和 makefile

进度条 #pragma once#include <stdio.h>#define NUM 102 #define BODY #define TOP 100 #define RIGHT >extern void processbar(int rate);#include "processBar.h" #include <string.h> #include <unistd.h>const char lable[] "|/-\…

排序试题解析(二)

8.4.3 01.在以下排序算法中&#xff0c;每次从未排序的记录中选取最小关键字的记录&#xff0c;加入已排序记录的 末尾&#xff0c;该排序算法是( A ). A.简单选择排序 B.冒泡排序 C.堆排序 D.直接插入排序 02&#xff0e;简单选择排序算法的比较次数和移动次数分别为( C )。…

苹果可能将OpenAI技术集成至iOS/iPadOS 18

&#x1f989; AI新闻 &#x1f680; 苹果可能将OpenAI技术集成至iOS/iPadOS 18 摘要&#xff1a;苹果正在与OpenAI就将GPT技术部署在iOS/iPadOS 18中进行谈判。这项技术被视为可能增强的Siri功能&#xff0c;即“AI聊天机器人”。除Siri外&#xff0c;新技术还可能改善Spotl…

RFC 6071: IP Security (IPsec) and Internet Key Exchange (IKE) Document Roadmap

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/96882d1fb67b4383bc77c4dd421f7b

LeetCode 面试题 17.08 —— 马戏团人塔

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 首先&#xff0c;我们对人的身高按照从小到大排序&#xff0c;特别注意&#xff0c;对于身高相等的人&#xff0c;要按照体重从高到低排序。这时候&#xff0c;序列已经满足了在上面的人要比下面的人矮一点&#…

Blender面操作

1.细分Subdivide -选择一个面 -右键&#xff0c;细分 -微调&#xff0c;设置切割次数 2.删除 -选择一个或多个面&#xff0c;按X键 -选择要删除的是面&#xff0c;线还是点 3.挤出面Extrude -选择一个面 -Extrude工具 -拖拽手柄&#xff0c;向外挤出 -微调&#xff…

【Linux】基础指令

文章目录 基础指令1. pwd 指令2. cd 指令3. ls 指令4. touch 指令5. mkdir 指令6. rmdir 和 rm 指令7. man 指令8. cp 指令9. mv 指令10. cat 指令11. more 和 less 指令12. head 和 tail 指令13. date 指令14. cal 指令15. find 指令16. grep 指令18. zip 和 unzip 指令19. ta…

科学高效备考AMC8和AMC10竞赛,吃透2000-2024年1850道真题和解析

多做真题&#xff0c;吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一&#xff0c;通过做真题&#xff0c;可以帮助孩子找到真实竞赛的感觉&#xff0c;而且更加贴近比赛的内容&#xff0c;可以通过真题查漏补缺&#xff0c;更有针对性的补齐知识的短板。 AMC8和AMC10…

元宇宙中的DAPP:你了解多少?

元宇宙是什么&#xff1f;这是一个在当今科技圈炙手可热的话题。而在元宇宙中&#xff0c;DAPP起着至关重要的角色&#xff0c;它作为连接现实世界与虚拟世界的桥梁&#xff0c;为未来的数字世界开启了一个全新的篇章。 一、元宇宙&#xff1a;一个虚拟的数字世界 元宇宙是一…

振弦采集仪在岩土工程监测中的误差分析及提高措施探讨振弦

振弦采集仪在岩土工程监测中的误差分析及提高措施探讨 振弦采集仪是岩土工程监测中常用的一种测量设备&#xff0c;广泛应用于地基沉降、岩土体固结、地下水位变化等监测工作中。然而&#xff0c;在实际应用中&#xff0c;振弦采集仪可能存在一些误差&#xff0c;影响监测结果…

vue学习的预备知识为学好vue打好基础

目录 Vue是什么 &#xff1f;如何使用Vue &#xff1f;Vue ApiVue入口apiVue实例apiVue函数api 无构建过程的渐进式增强静态HTMLVue模块化构建工具npmyarnWebpackvue-cliVite Vue是什么 &#xff1f; 文章基于Vue3叙述。 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于…

基于Springboot的考研资讯平台

基于SpringbootVue的考研资讯平台的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 考研资讯 报考指南 资料信息 论坛信息 后台登录 考研资讯管理 学生管理 资…

将静态资源解析成组件使用的库

vite版本的vite-plugin-svgr vite-plugin-svgr - npm 使用

实现SpringMVC底层机制(三)

文章目录 1.封装请求数据1.将方法的httpservletrequest和httpservletresponse参数封装到参数数组进行反射调用1.修改SunDispatcherServlet.java的executeDispatch方法2.debug测试 2.封装http请求参数1.需求分析2.自定义注解RequestsParam3.修改MonsterService接口&#xff0c;添…

Python PyTorch 获取 MNIST 数据

Python PyTorch 获取 MNIST 数据 1 PyTorch 获取 MNIST 数据2 PyTorch 保存 MNIST 数据3 PyTorch 显示 MNIST 数据 1 PyTorch 获取 MNIST 数据 import torch import numpy as np import matplotlib.pyplot as plt # type: ignore from torchvision import datasets, transform…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属&#xff0c;而web框架一直是悬而未决&#xff0c;说到底还是因为没有官方成熟的方案指引&#xff0c;大家各玩各的&#xff0c;互不兼容&#xff0c;白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…

【神经网络结构可视化】PlotNeuralNet的安装、测试及创建自己的神经网络结构可视化图形

文章目录 前提准备1、下载MikTeX2、下载Git bash3、下载PlotNeuralNet 进行测试1、解压PlotNeuralNet-master.zip2、打开Git bash3、 在my_project中查看生成的pdf文件 创建自己的神经网络结构可视化图形 前提准备 1、下载MikTeX 下载链接&#xff1a; MikTeX ( https://mikt…