【刷题】力扣每日一题 : 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.mzph.cn/news/139049.shtml

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

相关文章

001. 变量、环境变量

1、在终端中显示输出 shell脚本通常以shebang起始&#xff1a;#&#xff01;/bin/bash/ shebang是一个文本行&#xff0c;其中#!位于解释器路径之前。/bin/bash是Bash的解释器命令路径。bash将以#符号开头的行视为注释。脚本中只有第一行可以使用shebang来定义解释该脚本所使…

openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144) - 验证

文章目录 openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144) - 验证概述笔记重复数字IO的问题想法手工实现程序实现确定要摘掉的数字重合线自动化测试的问题测试程序的场景测试程序的运行效果测试程序实现备注END openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-14…

Leetcode刷题详解——优美的排列

1. 题目链接&#xff1a;526. 优美的排列 2. 题目描述&#xff1a; 假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm&#xff08;下标从 1 开始&#xff09;&#xff0c;只要满足下述条件 之一 &#xff0c;该数组就是一个 优美的排列 &#xff1a; perm[i] 能够被…

Win11专业版安装Docker Desktop,并支持映射主机的gpu

一、Windows环境下安装 Docker 必须满足: 1. 64位Windows 11 Pro(专业版和企业版都可以) 2. Microsoft Hyper-V,Hyper-V是微软的虚拟机,在win11上是自带的,我们只需要启动就可以了 二、下载Docker Desktop安装包 方式一:进入官网下载 https://docs.docker.com/desktop…

图论11-欧拉回路与欧拉路径+Hierholzer算法实现

文章目录 1 欧拉回路的概念2 欧拉回路的算法实现3 Hierholzer算法详解4 Hierholzer算法实现4.1 修改Graph&#xff0c;增加API4.2 Graph.java4.3 联通分量类4.4 欧拉回路类 1 欧拉回路的概念 2 欧拉回路的算法实现 private boolean hasEulerLoop(){CC cc new CC(G);if(cc.cou…

【已验证-直接用】微信小程序wx.request请求服务器json数据并渲染到页面

微信小程序的数据总不能写死吧&#xff0c;肯定是要结合数据库来做数据更新&#xff0c;而小程序数据主要是json数据格式&#xff0c;所以我们可以利用php操作数据库&#xff0c;把数据以json格式数据输出即可。 现在给大家讲一下微信小程序的wx.request请求服务器获取数据的用…

大数据毕业设计选题推荐-生产大数据平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

junit写搜索树测试

用法 assertTrue(range.contains("Two")); 2个参数,右边错就打印左边. AbstractSelfBalancingBinarySearchTree abt; AbstractBinarySearchTree.Node node; Before public void setUp() { abt new AbstractSelfBalancingBinarySearchTree() { Override protecte…

深度学习 python opencv 火焰检测识别 火灾检测 计算机竞赛

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

Mysql数据库 14.SQL语言 视图

一、视图的概念 视图&#xff1a;就是由数据库中一张或多张表根据特定的条件查询出的数据狗造成的虚拟表 二、视图的作用 安全性&#xff0c;简单性 三、视图的语法 语法 create view 视图表 as select_statement; 代码实现 #创建视图 将查询结果创建称为视图&#x…

百度王颖:百度文库以AI创作能力突破语言边界,促进思想碰撞和文化融通

1月9日&#xff0c;2023年世界互联网大会乌镇峰会“网络传播与文明交流互鉴论坛”召开。百度副总裁、互娱和垂类平台负责人王颖出席并发表“以技术搭建跨文化交流桥梁”主题演讲。她表示&#xff0c;在大模型的加持下&#xff0c;百度各个产品都在重构&#xff0c;通过技术助力…

第24章_mysql性能分析工具的使用

文章目录 1. 数据库服务器的优化步骤2.查看系统性能参数3. 统计SQL的查询成本&#xff1a;last_query_cost4. 定位执行慢的 SQL&#xff1a;慢查询日志4.1 开启慢查询日志参数4.2 查看慢查询数目4.3 测试慢sql语句&#xff0c;查看慢日志4.4 系统变量 log_output&#xff0c; l…

TensorFlow2.0教程3-CNN

` 文章目录 基础CNN网络读取数据卷积层池化层全连接层模型配置模型训练CNN变体网络简单的深度网络添加了其它功能层的深度卷积NIN网络文本卷积基础CNN网络 读取数据 import numpy as np import tensorflow as tf import tensorflow.keras as keras import tensorflow.keras.la…

uniapp中在组件中使用被遮挡或层级显示问题

uniapp中在组件中使用或croll-view标签内使用uni-popup在真机环境下会被scroll-view兄弟元素遮挡&#xff0c;在开发环境下和安卓系统中可以正常显示&#xff0c;但在ios中出现了问题 看了许多文章都没有找到问题的原因&#xff0c;最后看到这一个文章http://t.csdnimg.cn/pvQ…

138.随机链表的复制(LeetCode)

深拷贝&#xff0c;是指将该链表除了正常单链表的数值和next指针拷贝&#xff0c;再将random指针进行拷贝 想法一 先拷贝出一份链表&#xff0c;再对于每个节点的random指针&#xff0c;在原链表进行遍历&#xff0c;找到random指针的指向&#xff0c;最后完成拷贝链表random…

CSS3 分页、框大小、弹性盒子

一、CSS3分页&#xff1a; 网站有很多个页面&#xff0c;需要使用分页来为每个页面做导航。示例&#xff1a; <style> ul.pagination { display: inline-block; padding: 0; margin: 0; } ul.pagination li {display: inline;} ul.pagination li a { color: black; f…

SW如何显示样条曲线的控标

刚刚学习隔壁老王的sw画图时&#xff0c;怎么点都点不出样条曲线的控标&#xff0c;于是果断查询了一下解决方法&#xff0c;其实很简单&#xff0c;只不过是培训机构故意不说&#xff0c;叫你还解决不了&#xff0c;难受了就会花钱买他们的课了。毕竟如果学会了怎么解决问题了…

数据结构之双向链表

目录 引言 链表的分类 双向链表的结构 双向链表的实现 定义 创建新节点 初始化 打印 尾插 头插 判断链表是否为空 尾删 头删 查找与修改 指定插入 指定删除 销毁 顺序表和双向链表的优缺点分析 源代码 dlist.h dlist.c test.c 引言 数据结构…

devops完整搭建教程(gitlab、jenkins、harbor、docker)

devops完整搭建教程&#xff08;gitlab、jenkins、harbor、docker&#xff09; 文章目录 devops完整搭建教程&#xff08;gitlab、jenkins、harbor、docker&#xff09;1.简介&#xff1a;2.工作流程&#xff1a;3.优缺点4.环境说明5.部署前准备工作5.1.所有主机永久关闭防火墙…

学习c#的第五天

目录 C# 运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 C# 中的运算符优先级 C# 运算符 算术运算符 下表显示了 C# 支持的所有算术运算符。假设变量 A 的值为 10&#xff0c;变量 B 的值为 20&#xff0c;则&#xff1a; 运算符描述实例…