【刷题】力扣每日一题 : 381、2300、765

前言

本篇文章用于记录在做力扣每日一题的时候遇到的一些知识点以及自己的思路

381

题干

题目链接

我的思路及做题过程

思路1

我的想法是 记录每个字符串的字母出现个数 然后比较两个字符串是否有字母同时出现

class Solution {
public:int judge(string s1, string s2, int l1, int l2) {int n1[30] = { 0 }, n2[30] = { 0 };for (int i = 0; i < l1; i++) {n1[s1[i] - 97]++;}for (int i = 0; i < l2; i++) {n2[s2[i] - 97]++;}for (int i = 0; i < 26; i++) {if (n1[i] * n2[i] > 0) {return 0;}}return l1 * l2;}int maxProduct(vector<string>& words) {for (int i = 0; i < words.size(); i++) {for (int j = 0; j < words.size(); j++) {le = judge(words[i], words[j], words[i].size(), words[j].size());if (le > max) {max = le;}}}return max;}
private:int num[1010], le, max = 0;
};

re了 我写的时候就感觉它会re

优化1

judge函数没必要去记录字母出现个数 直接两两比较 如果相等直接返回0即可

    int judge(string s1, string s2, int l1, int l2) {for (int i = 0; i < l1; i++){for (int j = 0; j < l2; j++) {if (s1[i] == s2[j]){return 0;}}}return l1 * l2;}

优化2

maxProduct函数中for循环的范围可以修改一下(比较简单的优化方式)
j的范围变为

            for (int j = i + 1; j < words.size(); j++) {

优化3

数据比较大的时候 每次调用judge函数都需要比较长的运行时间
我们可以进一步缩小使用judge函数的范围

当l1*l2>max的时候 再去进行一一比较

最终代码

class Solution {
public:int judge(string s1, string s2, int l1, int l2, int max) {if(l1 * l2 > max){for (int i = 0; i < l1; i++) {for (int j = 0; j < l2; j++) {if (s1[i] == s2[j]) {return 0;}}}return l1 * l2;}return 0;}int maxProduct(vector<string>& words) {for (int i = 0; i < words.size(); i++) {for (int j = i + 1; j < words.size(); j++) {le = judge(words[i], words[j], words[i].size(), words[j].size(), max);if(le){max = le;}}}return max;}
private:int num[1010], le, max = 0;
};

题解中的其他做法

位运算

跟我的思路一有一些相同之处 : 统计每个字母出现次数
不同的是 它使用了位运算
移位操作符、按位或 和 &

先计算出每个单词中有什么字母出现(数组的映射 不再解释了) 左移一位
之后与原数值进行按位或

                masks[i] |= 1 << (word[j] - 'a');

最后 将两个数组中的值进行按位与 为0 就与max进行比较
(位运算太妙了

还有用哈希表进行优化的 (我是蒟蒻 我不会 呜呜呜呜呜呜呜呜呜

2300

题干

题目链接

我的思路及做题过程

思路1

第一遍写的时候
我直接两个for循环遍历了一下

re了 很正常 毕竟是中等题

思路2

二分法双指针
先用sort排序 之后再利用双指针 逐渐缩小范围 减少程序运行时间

二分法部分的代码

int le = 0, ri = po.size() - 1, mid;
while (le <= ri)
{mid = (le + ri) / 2;a = sp[i], b = po[mid];if (a * b < su){le = mid + 1;}else{ri = mid - 1;}
}

最终代码

class Solution {
public:vector<int> successfulPairs(vector<int>& sp, vector<int>& po, long long su) {sort(po.begin(), po.end());for (int i = 0; i < sp.size(); i++){int le = 0, ri = po.size() - 1, mid;while (le <= ri){//mid = le + (ri - le) >> 1;mid = (le + ri) / 2;a = sp[i], b = po[mid];if (a * b < su){le = mid + 1;}else{ri = mid - 1;}}pairs.push_back(po.size() - le);}return pairs;}private:vector<int>pairs;long long a, b, c;
};

注意点

在学习二分算法的时候 我们肯定都接触过位运算 并且知道位运算比乘除法要快
那在这道题中 我们可不可以用位运算呢 大家可以试一下
下面提供一下我调试时的代码

class Solution {
public:vector<int> successfulPairs(vector<int>& sp, vector<int>& po, long long su) {sort(po.begin(), po.end());for (int i = 0; i < sp.size(); i++){int le = 0, ri = po.size() - 1, mid;while (le <= ri){mid = le + (ri - le) >> 1;a = sp[i], b = po[mid];if (a * b < su){le = mid + 1;}else{ri = mid - 1;}}pairs.push_back(po.size() - 1);}return pairs;}private:vector<int>pairs;int flag = 1;long long x = 0;long long a, b, c;
};int main() {Solution s1;vector<int>po, sp;po.push_back(1);po.push_back(2);po.push_back(3);po.push_back(4);po.push_back(5);sp.push_back(5);sp.push_back(1);sp.push_back(3);s1.successfulPairs(sp, po, 7);return 0;
}

答案是不可以 会陷入死循环

分析

我们先循环两次 变成下面这种情况
在这里插入图片描述

接下来关键的要来了
我们来到第三次循环 遇到了这条语句

mid = left + (right - left) >>1;

那么(right - left)此时是 1-1 为0
0>>1仍未0
接下来进入if的第一种情况

left = mid + 1;

left = 1

第四次循环中与第三次循环情况相同
所以 陷入了死循环

mid = (le + ri) / 2;

不会死循环 因为1+1/2 == 1

题解中的其他做法

我看到官解中虽然思路和我写的差不多 但是他用到了新的知识
upper_bound函数它返回一个迭代器,指向在排序序列中第一个大于或等于给定值的元素。如果不存在大于或等于给定值的元素,则返回序列的尾迭代器

lower_bound和upper_bound的区别是后者返回的是大于给定值的元素的迭代器
前者返回的是大于等于给定值元素的迭代器

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

765

温馨提示

下面是我写着玩的 能过纯粹是数据量小
所以下面的题解也不具有参考性

题干

题目链接

我的思路及做题过程

第一遍代码

class Solution {
public:int minSwapsCouples(vector<int>& row) {for (int i = 1; i < row.size(); i++) {if (!(abs(row[i - 1] - row[i]) == 1)) {for (int j = i; j < row.size(); j++) {if ((abs(row[j] - row[i]) == 1)) {swap(row[j], row[i]);num++;break;}}}}return num;}
private:int num = 0;
};

惨不忍睹

问题

我找出来了两个问题

1. for循环
我因为担心越界 所以把范围写成1~n-1

但实际上 可以一对一对的去判断(并且题目已经说明row的长度是偶数) 即i += 2

2. if语句
if语句的判断条件有问题
不能用取绝对值的方法 因为2 和 3不是一对 但绝对值是1 这不符合题意
可以通过判断奇偶性 来进行加一或者减一

修改之后的代码

class Solution {
public:int minSwapsCouples(vector<int>& row) {for (int i = 0; i < row.size(); i += 2) {if (((row[i] % 2 == 0) ? row[i] + 1 : row[i] - 1) != row[i + 1]) {for (int j = i + 2; j < row.size(); j++) {if (((row[i] % 2 == 0) ? row[i] + 1 : row[i] - 1) == row[j]) {swap(row[j], row[i + 1]);num++;}}}}return num;}
private:int num = 0;
};

题解中的其他做法

官解中的并查集和bfs我都不会 所以没仔细看
我在其他的题解中看到了一种做法 利用异或

以下代码转自
这个博主的解法

简单来说就是 2和3这一对情侣 通过与1异或可以得到另一半(又是美妙 的位运算)

class Solution {
public://参考大佬的异或,2与1异或得到3,3与1异或得到2;也就是说每一对只要异或就能得到彼此的“另一半”,只要找到并交换就行int minSwapsCouples(vector<int>& row) {int n = row.size();int cnt = 0;for(int i = 0; i < n - 1; i++){int x = row[i];   //某个人int y = x ^ 1;  //他的另一半if(row[i + 1] != y){  //情侣不挨着,就往后搜for(int k = i + 2; k < n; k++){if(row[k] == y){//找到了另一半,交换int temp = row[i + 1];row[i + 1] = row[k];row[k] = temp;cnt++;break;   //找到就退回上一层循环,判断下一对是不是情侣坐一起}}}}return cnt;}
};

结语

我打算新开一个刷题的专栏 用于总结复盘

加油吧

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode因为大文件而无限崩溃的问题,窗口意外终止(原因:“oom“,代码:“-536870904“

复制了一大堆的代码&#xff08;好几兆&#xff09;到一个文件里&#xff0c;然后就导致 vscode 卡死&#xff0c; 之后就算把该文件删掉了&#xff0c;打开vscode还是会默认打开该文件而卡死 解决办法&#xff1a; win R 输入 %appdata%/code/ 删除该文件夹下的 backups/ 文件…

索尼RSV文件怎么恢复为MP4视频

索尼相机RSV是什么文件&#xff1f; 如果您的相机是索尼SONY A7S3&#xff0c;A7M4&#xff0c;FX3&#xff0c;FX3&#xff0c;FX6&#xff0c;或FX9等&#xff0c;有时录像会产生一个RSV文件&#xff0c;而没有MP4视频文件。RSV其实是MP4的前期文件&#xff0c;经我对RSV文件…

CSS特效006:绘制不断跳动的心形

css实战中&#xff0c;怎么绘制不断跳动的心形呢&#xff1f; 绘图的时候主要用到了transform: rotate(-45deg); transform-origin: 0 100%; transform: rotate(45deg); transform-origin: 100% 100%; 动画使用keyframes 时间上为infinite。 效果图 源代码 /* * Author: 大剑…

切换数据库的临时表空间为temp1 / 切换数据库的undo表空间为 undotbs01

目录 ​编辑 一、切换临时表空间 1、登录数据库 2、查询默认临时表空间 3、创建临时表空间temp1&#xff08;我们的目标表空间&#xff09; 4、修改默认temp表空间 5、查询用户默认临时表空间 6、命令总结&#xff1a; 二、切换数据库的undo表空间 1、查询默认undo表…

【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固

​ 摘要 在开发iOS应用时&#xff0c;保护应用程序的安全是非常重要的。本文将介绍一种使用ipaguard混淆加固的方法来保护iOS应用的安全。通过字符串混淆、类名和方法名混淆、程序结构混淆加密以及反调试、反注入等主动保护策略&#xff0c;可以有效地保护应用程序的安全性。 …

SparkSQL语法优化

SparkSQL在整个执行计划处理的过程中&#xff0c;使用了Catalyst 优化器。 1 基于RBO的优化 在Spark 3.0 版本中&#xff0c;Catalyst 总共有 81 条优化规则&#xff08;Rules&#xff09;&#xff0c;分成 27 组&#xff08;Batches&#xff09;&#xff0c;其中有些规则会被归…

2.docker镜像的导入导出

目录 概述docker 常用命令下载导出导入镜像结束 概述 docker 常用命令 本章节使用到的命令&#xff0c;总结在此&#xff0c;后面有使用案例。 命令作用docker images显示镜像docker rmi $(docker images -q)删除系统上所有的镜像docker rmi -f强制删除多个镜像 &#xff1a…

LeetCode146.LRU缓存

写了一个小时&#xff0c;终于把示例跑过了&#xff0c;没想到啊提交之后第19/22个测试用例没过 我把测试用例的输出复制在word上看看和我的有什么不同&#xff0c;没想到有18页的word&#xff0c;然后我一直检查终于找出了问题&#xff0c;而且这个bug真的太活该了&#xff0c…

云栖大会丨桑文锋:打造云原生数字化客户经营引擎

近日&#xff0c;2023 云栖大会在杭州举办。今年云栖大会回归了 2015 的主题&#xff1a;「计算&#xff0c;为了无法计算的价值」。神策数据创始人 & CEO 桑文锋受邀出席「生态产品与伙伴赋能」技术主题&#xff0c;并以「打造云原生数字化客户经营引擎」为主题进行演讲。…

男科医院服务预约小程序的作用是什么

医院的需求度从来都很高&#xff0c;随着技术发展&#xff0c;不少科目随之衍生出新的医院的&#xff0c;比如男科医院、妇科医院等&#xff0c;这使得目标群体更加精准&#xff0c;同时也赋能用户可以快速享受到服务。 当然相应的男科医院在实际经营中也面临痛点&#xff1a;…

微服务-我对Spring Clound的理解

官网&#xff1a;https://spring.io/projects/spring-cloud 官方说法&#xff1a;Spring Cloud 为开发人员提供了快速构建分布式系统中一些常见模式的工具&#xff08;例如配置管理、服务发现、熔断器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话…

什么是Amazon Simple Email Service(SES 群发邮件)

Amazon Simple Email Service&#xff08;Amazon SES&#xff09;让您可以使用 Amazon SES API 或 SMTP 接口放心地联络到客户&#xff0c;而无需使用本地简单邮件传输协议&#xff08;Simple Mail Transfer Protocol&#xff0c;SMTP&#xff09;电子邮件服务器。 目录 什么是…

最新支付宝转卡码生成之转账源代码(隐藏部分卡号)

一、需要准备好自己的卡号、名称、以及对应的姓名 二、然后将自己的信息填入下面的代码中 三、然后将拼接好的代码&#xff0c;利用转码技术生产对应的二维码 四、这样一个跳转银行卡二维码的转账码就做好了 效果演示&#xff1a;如下 支付宝扫码、跳转码、转卡码、隐藏卡号…

classification_report分类报告的含义

classification_report分类报告 基础知识混淆矩阵&#xff08;Confusion Matrix&#xff09;TP、TN、FP、FN精度&#xff08;Precision&#xff09;准确率&#xff08;Accuracy&#xff09;召回率&#xff08;Recall&#xff09;F1分数&#xff08;F1-score&#xff09; classi…

Linux编辑器---vim的使用

Vim是一个高度可配置的文本编辑器&#xff0c;它是操作Linux的一款利器&#xff0c;旨在高效地创建和更改任何类型的文本。这款编辑器起源于"vi"&#xff0c;并在此基础上发展出了众多新的特性。Vim被普遍推崇为类Vi编辑器中最好的一个&#xff0c;事实上真正的劲敌来…

asp.net core自定义异常过滤器并记录到Log4Net日志

1.创建异常过滤器特性 using Log4Net.Controllers; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters;namespace Log4NetTest {public class CustomerExceptionFilterAttribute : Attribute, IExceptionFilter{private readonly ILogger<CustomerE…

docker通过nginx代理tomcat-域名重定向

通过昨天的调试&#xff0c;今天做这个域名就简单了&#xff0c; 正常我们访问网站一般都是通过域名比如&#xff0c;www.baidu.com对吧&#xff0c;有人也通过ip&#xff0c;那么这个怎么做呢&#xff1f;物理机windows可以通过域名访问虚拟机linux的nginx代理转向tomcat服务…

【多线程 - 01、概述】

进程 几乎所有的操作系统都支持进程概念&#xff0c;进程是处于运行过程中的程序&#xff0c;进程是操作系统中进行资源分配的基本单位。 三个基本特征 独立性&#xff1a;指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。而对于未建立任何进程的程序&…

257. 二叉树的所有路径

描述 : 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 题目 : LeetCode 257.二叉树的所有路径 : 257. 二叉树的所有路径 分析 : 我们可以注意到有几个叶子节点&#xff0c;就有…

基于SpringBoot+Vue+mysql卓越导师双选系统设计与实现

博主介绍&#xff1a;✌Csdn特邀作者、博客专家、博客云专家、B站程序阿龙带小白做毕设系列&#xff0c;项目讲解、B站粉丝排行榜前列、专注于Java技术领域和毕业项目实战✌ 系统说明简介&#xff1a; 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较…