leetcode解题思路分析(九十六)832 - 838 题

2024-09-05 04:48

本文主要是介绍leetcode解题思路分析(九十六)832 - 838 题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. 翻转图像
    给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]。反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]。

在一次遍历中,即进行逆序也进行值的反转,用双指针完成任务

class Solution {
public:vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) {int n = image.size();for (int i = 0; i < n; i++) {int left = 0, right = n - 1;while (left < right) {if (image[i][left] == image[i][right]) {image[i][left] ^= 1;image[i][right] ^= 1;}left++;right--;}if (left == right) {image[i][left] ^= 1;}}return image;}
};
  1. 字符串中的查找与替换
    某个字符串 S 需要执行一些替换操作,用新的字母组替换原有的字母组(不一定大小相同)。

唯一的问题是Indices可能不是递增,所以先遍历一遍看看哪些需要改哪些不用改,然后依次修改即可


class Solution {
public:string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {stringstream ss;// 构建mark表示是否需要被替换int mark[s.size()];memset(mark, 0, sizeof(mark));for (int i = 0; i < indices.size(); ++i){if (s.substr(indices[i], sources[i].size()) == sources[i]){mark[indices[i]] = i+1;}}// 默认值是0,所以必须>0才考虑int n = s.size();int i = 0;while (i < n){if (mark[i] == 0){ss << s[i];++i;}else{ss << targets[mark[i]-1];i += sources[mark[i]-1].size();}}return ss.str();}
};
  1. 树中距离之和
    给定一个无向、连通的树。树中有 N 个标记为 0…N-1 的节点以及 N-1 条边 。第 i 条边连接节点 edges[i][0] 和 edges[i][1] 。返回一个表示节点 i 与其他所有节点距离之和的列表 ans。

重复很多相同的子情况,所以用动态规划很合理。为了减少计算量,这里有个很巧妙的设计:经过一次树形动态规划后其实我们获得了在 u 为根的树中,每个节点为根的子树的答案 dp,我们可以利用这些已有信息来优化时间复杂度。假设 u的某个后代节点为 v,如果要算 v 的答案,本来我们要以 v 为根来进行一次树形动态规划。但是利用已有的信息,我们可以考虑树的形态做一次改变,让 v 换到根的位置,u 变为其孩子节点,同时维护原有的 dp 信息。在这一次的转变中,我们观察到除了 u 和 v 的 dp 值,其他节点的 dp 值都不会改变,因此只要更新 dp[u] 和 dp[v] 的值即可。

class Solution {
public:vector<int> ans, sz, dp;vector<vector<int>> graph;void dfs(int u, int f) {sz[u] = 1;dp[u] = 0;for (auto& v: graph[u]) {if (v == f) {continue;}dfs(v, u);dp[u] += dp[v] + sz[v];sz[u] += sz[v];}}void dfs2(int u, int f) {ans[u] = dp[u];for (auto& v: graph[u]) {if (v == f) {continue;}int pu = dp[u], pv = dp[v];int su = sz[u], sv = sz[v];dp[u] -= dp[v] + sz[v];sz[u] -= sz[v];dp[v] += dp[u] + sz[u];sz[v] += sz[u];dfs2(v, u);dp[u] = pu, dp[v] = pv;sz[u] = su, sz[v] = sv;}}vector<int> sumOfDistancesInTree(int n, vector<vector<int>>& edges) {ans.resize(n, 0);sz.resize(n, 0);dp.resize(n, 0);graph.resize(n, {});for (auto& edge: edges) {int u = edge[0], v = edge[1];graph[u].emplace_back(v);graph[v].emplace_back(u);}dfs(0, -1);dfs2(0, -1);return ans;}
};
  1. 图像重叠
    给你两个图像 img1 和 img2 ,两个图像的大小都是 n x n ,用大小相同的二维正方形矩阵表示。(并且为二进制矩阵,只包含若干 0 和若干 1 )转换其中一个图像,向左,右,上,或下滑动任何数量的单位,并把它放在另一个图像的上面。之后,该转换的 重叠 是指两个图像都具有 1 的位置的数目。(请注意,转换 不包括 向任何方向旋转。)最大可能的重叠是多少?

计算便宜量,然后比较取最大值

class Solution {
public:const int N=30;int cnt[4000];int largestOverlap(vector<vector<int>>& img1, vector<vector<int>>& img2) {int n=img1.size();using pii=pair<int,int>;int res=0;vector<pii> vec;for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(img2[i][j])vec.push_back({i,j});    //找出img2中所有1的坐标for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(img1[i][j]){for(auto& [row,col]:vec)   //遍历img2中所有1的坐标{int a=row-i+N;         //计算img1到img2的偏移量,+N防止负数int b=col-j+N;cnt[flat(a,b)]++;       //相同偏移量对应计数+1res=max(res,cnt[flat(a,b)]);}}return res;}int flat(int& row,int& col) //编码计算{return (row<<6)+col;}
};
  1. 矩形重叠
    矩形以列表 [x1, y1, x2, y2] 的形式表示,其中 (x1, y1) 为左下角的坐标,(x2, y2) 是右上角的坐标。矩形的上下边平行于 x 轴,左右边平行于 y 轴。如果相交的面积为 正 ,则称两矩形重叠。需要明确的是,只在角或边接触的两个矩形不构成重叠。给出两个矩形 rec1 和 rec2 。如果它们重叠,返回 true;否则,返回 false 。

两矩形相交,则长和宽的投影必相交,即x/y轴的两条线都要相交才算重叠

class Solution {
public:bool isRectangleOverlap(vector<int>& rec1, vector<int>& rec2) {return (min(rec1[2], rec2[2]) > max(rec1[0], rec2[0]) &&min(rec1[3], rec2[3]) > max(rec1[1], rec2[1]));}
};
  1. 新21点
    爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下:
    爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 每次抽取都是独立的,其结果具有相同的概率。
    当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少?

概率论数学题

class Solution {
public:double new21Game(int n, int k, int maxPts) {if (k == 0) {return 1.0;}vector<double> dp(k + maxPts);for (int i = k; i <= n && i < k + maxPts; i++) {dp[i] = 1.0;}dp[k - 1] = 1.0 * min(n - k + 1, maxPts) / maxPts;for (int i = k - 2; i >= 0; i--) {dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts;}return dp[0];}
};
  1. 推多米诺
    一行中有 N 张多米诺骨牌,我们将每张多米诺骨牌垂直竖立。
    在开始时,我们同时把一些多米诺骨牌向左或向右推。
    返回表示最终状态的字符串。

L和R隔开的部分是一个个子数组,每个子数组再取中间值考虑每个成员的倒向即可


class Solution {
public:string pushDominoes(string dominoes) {int n = dominoes.size();int* diff = new int[n];memset(diff, 0, sizeof(int)*n);// 从左往右int weight = 0;for (int i = 0; i < n; ++i){if (dominoes[i] == 'R'){weight = n;}else if (dominoes[i] == 'L'){weight = 0;}else{weight = max(weight-1, 0);}diff[i] = weight;}// 从右往左weight = 0;for (int i = n-1; i >= 0; --i){if (dominoes[i] == 'L'){weight = n;}else if (dominoes[i] == 'R'){weight = 0;}else{weight = max(weight-1, 0);}diff[i] -= weight;}for (int i = 0; i < n; ++i){dominoes[i] = diff[i] > 0 ? 'R' : (diff[i] < 0 ? 'L' : '.');}return dominoes;}
};

这篇关于leetcode解题思路分析(九十六)832 - 838 题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137988

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3