leetcode解题思路分析(五十四)462 - 468 题

2024-09-05 04:58

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

  1. 最少移动次数使数组元素相等2
    给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。

找到中位数,和中位数的差值就是最小值

class Solution {
public:int minMoves2(vector<int>& nums) {int res = 0, i = 0, j = nums.size() - 1;sort(nums.begin(), nums.end());while(i < j) {res += nums[j--] - nums[i++];}return res;}
};
  1. 岛屿的周长
    给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

遍历一遍,减去计算多的边即可

class Solution {
public:int islandPerimeter(vector<vector<int>>& grid) {if (grid.size() == 0 || grid[0].size() == 0) return 0;int ret = 0, multi = 0;for (int i = 0; i < grid.size(); i++){for (int j = 0; j < grid[0].size(); j++){if (grid[i][j]){ret += 4;if (i < grid.size() - 1){if (grid[i + 1][j])multi += 2;}if (j < grid[0].size() - 1){if (grid[i][j + 1])multi += 2;}}}}return ret - multi;}
};
  1. 我能赢吗
    给定一个整数 maxChoosableInteger (整数池中可选择的最大数)和另一个整数 desiredTotal(累计和),判断先出手的玩家是否能稳赢(假设两位玩家游戏时都表现最佳)?

记忆化递归求解

class Solution {
public:bool canIWin(int maxChoosableInteger, int desiredTotal) {if (desiredTotal <= 0)return true;int sum = 0;int maxbits = 0;for (int i = maxChoosableInteger; i >= 1 && sum < desiredTotal; i--) {sum += i;maxbits += (1 << (i - 1));}if (sum < desiredTotal)return false;vector<bool> dp0(maxbits + 1);vector<bool> dp1(maxbits + 1);for (int i = maxbits; i >= 0; i--) {int s = 0;for (int k = 1; k <= maxChoosableInteger; k++)if ((1 << (k - 1)) & i)s += k;if (s >= desiredTotal) {dp0[i] = false;dp1[i] = true;} else {dp0[i] = false;dp1[i] = true;for (int j = 1; j <= maxChoosableInteger; j++) {if ((1 << (j - 1)) & i)continue;if (dp1[i] && ((s + j >= desiredTotal) || !dp0[((1 << (j - 1)) | i)]))dp1[i] = false;if (!dp0[i] && ((s + j >= desiredTotal) || dp1[((1 << (j - 1)) | i)]))dp0[i] = true;if (dp0[i] && !dp1[i])break;}}}return dp0[0];}
};
  1. 统计重复个数
    由 n 个连接的字符串 s 组成字符串 S,记作 S = [s,n]。例如,[“abc”,3]=“abcabcabc”。如果我们可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,“abc” 可以从 “abdbec” 获得,但不能从 “acbbe” 获得。现在给你两个非空字符串 s1 和 s2(每个最多 100 个字符长)和两个整数 0 ≤ n1 ≤ 106 和 1 ≤ n2 ≤ 106。现在考虑字符串 S1 和 S2,其中 S1=[s1,n1] 、S2=[s2,n2] 。请你找出一个可以满足使[S2,M] 从 S1 获得的最大整数 M 。
class Solution {
public:int getMaxRepetitions(string s1, int n1, string s2, int n2) {if (n1 == 0) {return 0;}int s1cnt = 0, index = 0, s2cnt = 0;// recall 是我们用来找循环节的变量,它是一个哈希映射// 我们如何找循环节?假设我们遍历了 s1cnt 个 s1,此时匹配到了第 s2cnt 个 s2 中的第 index 个字符// 如果我们之前遍历了 s1cnt' 个 s1 时,匹配到的是第 s2cnt' 个 s2 中同样的第 index 个字符,那么就有循环节了// 我们用 (s1cnt', s2cnt', index) 和 (s1cnt, s2cnt, index) 表示两次包含相同 index 的匹配结果// 那么哈希映射中的键就是 index,值就是 (s1cnt', s2cnt') 这个二元组// 循环节就是;//    - 前 s1cnt' 个 s1 包含了 s2cnt' 个 s2//    - 以后的每 (s1cnt - s1cnt') 个 s1 包含了 (s2cnt - s2cnt') 个 s2// 那么还会剩下 (n1 - s1cnt') % (s1cnt - s1cnt') 个 s1, 我们对这些与 s2 进行暴力匹配// 注意 s2 要从第 index 个字符开始匹配unordered_map<int, pair<int, int>> recall;pair<int, int> pre_loop, in_loop;while (true) {// 我们多遍历一个 s1,看看能不能找到循环节++s1cnt;for (char ch: s1) {if (ch == s2[index]) {index += 1;if (index == s2.size()) {++s2cnt;index = 0;}}}// 还没有找到循环节,所有的 s1 就用完了if (s1cnt == n1) {return s2cnt / n2;}// 出现了之前的 index,表示找到了循环节if (recall.count(index)) {auto [s1cnt_prime, s2cnt_prime] = recall[index];// 前 s1cnt' 个 s1 包含了 s2cnt' 个 s2pre_loop = {s1cnt_prime, s2cnt_prime};// 以后的每 (s1cnt - s1cnt') 个 s1 包含了 (s2cnt - s2cnt') 个 s2in_loop = {s1cnt - s1cnt_prime, s2cnt - s2cnt_prime};break;} else {recall[index] = {s1cnt, s2cnt};}}// ans 存储的是 S1 包含的 s2 的数量,考虑的之前的 pre_loop 和 in_loopint ans = pre_loop.second + (n1 - pre_loop.first) / in_loop.first * in_loop.second;// S1 的末尾还剩下一些 s1,我们暴力进行匹配int rest = (n1 - pre_loop.first) % in_loop.first;for (int i = 0; i < rest; ++i) {for (char ch: s1) {if (ch == s2[index]) {++index;if (index == s2.size()) {++ans;index = 0;}}}}// S1 包含 ans 个 s2,那么就包含 ans / n2 个 S2return ans / n2;}
};

467 环绕字符串中唯一的子字符串
现在我们有了另一个字符串 p 。你需要的是找出 s 中有多少个唯一的 p 的非空子串,尤其是当你的输入是字符串 p ,你需要输出字符串 s 中 p 的不同的非空子串的数目。

找出连续的子串,然后计算其可以组成的子串长度,最后累加

class Solution {
public:int findSubstringInWraproundString(string p) {if (!p.size()) return 0;vector<int> vec(128, 0);int curlen = 1;int result = 1;vec[p[0]] = 1;for (int i = 1; i < p.size(); ++i) {if (p[i] == p[i-1] + 1 || p[i] == 'a' && p[i-1] == 'z') {curlen ++;} else {curlen = 1;}if (curlen > vec[p[i]]) {result += curlen - vec[p[i]];vec[p[i]] = curlen;}}return result;}
};
  1. 验证IP地址
    编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

按规则匹配即可

class Solution {public:string validIPAddress(string IP) {string str1 = "IPv4";string str2 = "IPv6";string str3 = "Neither";//ipv4的限制 开头不能为0 有4组值 并且不能出现空数组int i = 0;bool ipv4 = false;int index = 0;bool ipv6 = false;if(IP.length() == 0 || IP[IP.length()-1] == ':' || IP[IP.length()-1] == '.' || IP[0] == '0') return str3;while(i < IP.length()){stack<char> s;while(i < IP.length() && IP[i] != '.' && IP[i] != ':') { s.push(IP[i++]);}index++;if(IP[i] == '.' && i < IP.length()) ipv4 = true;if(IP[i] == ':' && i < IP.length()) ipv6 = true;if(ipv4 && ipv6) return str3;  if(ipv4){if(index > 4 || s.empty()) {return str3;}int tmp = 0;int k = 1;int n = s.size();while(!s.empty()){if(s.top() == '-') return str3;int tmp2 = (s.top() - '0');s.pop();//这里判断首字母是否为0if(s.empty() && tmp2 == 0 && n != 1) return str3;tmp += tmp2 * k;k = k * 10;if(tmp > 255) return str3;}if(tmp > 255) return str3;}else{//可以0开头 不能出现连续的0 并且0的个数大于1if(index > 8 || s.empty()) {return str3;}int n = s.size();if(n > 4) return str3;while(!s.empty()){if(s.top() == '-') return str3;if( s.top() >= 'A' && s.top() <= 'Z' && s.top() > 'F') return str3;if( s.top() >= 'a' && s.top() <= 'z' && s.top() > 'f') return str3;s.pop();}}i++;}if(ipv4 && index == 4) return str1;else return index == 8 ? str2 : str3;}
};

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



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

相关文章

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