1、题目信息

  • https://leetcode.cn/problems/aseY1I/description/
给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。示例 1:
输入:words = ["abcw","baz","foo","bar","fxyz","abcdef"]
输出:16 
解释:这两个单词为 "abcw", "fxyz"。它们不包含相同字符,且长度的乘积最大。示例 2:
输入:words = ["a","ab","abc","d","cd","bcd","abcd"]
输出:4 
解释:这两个单词为 "ab", "cd"。示例 3:
输入:words = ["a","aa","aaa","aaaa"]
输出:0 
解释:不存在这样的两个单词。

2、审题

  • 输入一个字符串数组,数组两个元素中的字符串,可能存在相同的字符,要求寻找没有相同字符的两个字符串,要求他们的长度乘积最大并返回
  • 如果任意两个字符串都存在相同的字符,结果返回0

3、解法1:暴力解法

思路:

  • 解题关键在于:寻找出两个字符串,他们之间不存在相同的字符
    • 四层for循环,外双层for循环,从字符串数组中寻找两个不同的字符串,内层for循环判断两个字符串两两是否存在相同的字符
    • 如果存在相同字符,退出内部两层for循环,从新寻找其他字符串组合
    • 如果不存在相同字符,求出两个字符串的最大乘积
  • 暴力解法会超出时间限制

代码实现:

int maxProduct1(vector<string> &words)
{int res = 0;int size = words.size();for (int i = 0; i < size; i++){for (int j = i + 1; j < size; j++){std::string str1 = words[i];std::string str2 = words[j];int len1 = str1.length();int len2 = str2.length();int h = 0;for (; h < len1; h++){// 遍历str1字符串中的字符,判断该字符在str1中是否存在,存在则退出当前for循环bool find = false;for (int g = 0; g < len2; g++){if (str1[h] == str2[g]){find = true;break;}}if (find){break;}}if (h == len1) // h遍历到str1字符串末尾,说明不存在相同字符{int productLen = len1 * len2;res = std::max(res, productLen);}}}return res;
}

4、解法2:哈希表解法

思路:

  • 暴力解法中有四层for循环,其中外层两个for循环是寻找两个需要比较的字符串,内层两个for循环是判断两个字符串是否有相同的字符
  • 内层for循环可简化,通过哈希表的方式记录每个字符串中,单个字符是否出现过
    • 哈希表使用二维数组结构,一维数组元素存储的是数组中的单个字符串,一维数组长度是字符串数组长度,
    • 二维数组内层存储的是单个字符串是否出现-使用bool表示,因为字符串由小写字母组成,所以二维数组的长度是26

代码实现:

int maxProduct2(vector<string> &words)
{int res = 0;int size = words.size();vector<vector<bool>> arr(size, vector<bool>(26, false));// 遍历单个字符串,判断单个字符出现的位置,在出现的位置上设置arr数组元素为bool值for (int i = 0; i < size; i++){std::string str = words[i];for (int j = 0; j < str.length(); j++){arr[i][str[j] - 'a'] = true;}}// 字符串两两判断是否存在相同字符for (int i = 0; i < size; i++){for (int j = i + 1; j < size; j++){std::string str1 = words[i];std::string str2 = words[j];int len1 = str1.length();int len2 = str2.length();int h = 0;for (; h < len1; h++){int chIndex = str1[h] - 'a'; // 是第几个字符if (arr[i][chIndex] && arr[j][chIndex]){break;}}if (h == len1){// 没有相同的字符int productLen = len1 * len2;res = std::max(res, productLen);}}}return res;
}

优化:

  • 第三层for循环改为遍历26个字符,判断两个字符是否存在相同的字符
int maxProduct3(vector<string> &words)
{int res = 0;int size = words.size();vector<vector<bool>> arr(size, vector<bool>(26, false));// 遍历单个字符串,判断单个字符出现的位置,在出现的位置上设置arr数组元素为bool值for (int i = 0; i < size; i++){std::string str = words[i];for (int j = 0; j < str.length(); j++){arr[i][str[j] - 'a'] = true;}}// 字符串两两判断是否存在相同字符for (int i = 0; i < size; i++){for (int j = i + 1; j < size; j++){int h = 0;for (; h < 26; h++){if (arr[i][h] && arr[j][h]){break;}}if (h == 26){// 没有相同的字符int productLen = words[i].length() * words[j].length();res = std::max(res, productLen);}}}return res;
}

5、解法3:位运算

思路:

  • 之前26个字母位置存在的是bool类型,表示字符串包含的字母在26个字母位置是否存在
  • bool类型只有true和false,也可以替换为使用int类型,该字母存在值为1,否则为0
    那最后如何判断两个字符中是否存在相同的字母呢?
  • 使用一维整数数组,一个int整数类型长度为32字节,可以满足26个的标识
  • 遍历所有的字符串数组,再遍历单个字符串,获取到字符,往左移该字符在26个字母中的位置,并且标记为1
  • 最后两个整数进行&与运算,其结果为1,说明存在相同字母

将字符串中包含的字母标记,使用int类型进行表示,转换成二进制方式

i:0 ,word:abcw ,arr item:4194311
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
i:1 ,word:baz ,arr item:33554435
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
i:2 ,word:foo ,arr item:16416
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0
i:3 ,word:bar ,arr item:131075
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
i:4 ,word:fxyz ,arr item:58720288
0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
i:5 ,word:abcdef ,arr item:63
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1

代码实现:

int maxProduct(vector<string> &words)
{int res = 0;int size = words.size();vector<int> arr(size, 0);for (int i = 0; i < size; i++){std::string str = words[i];for (int j = 0; j < str.length(); j++){arr[i] |= (1 << (str[j] - 'a'));}}// 字符串两两判断是否存在相同字符for (int i = 0; i < size; i++){for (int j = i + 1; j < size; j++){if ((arr[i] & arr[j]) == 0){// 没有相同的字符int productLen = words[i].length() * words[j].length();res = std::max(res, productLen);}}}return res;
}

6、总结

  • 输入的是一个字符串数组,要从中选出两个不同的字符串元素,需要通过两层for循环去查找
  • 而要判断两个字符串中是否存在相同的字符,则需要对两个字符串分别进行遍历,判断是否存在相同的字符
  • 采用空间换时间的方式,先对字符串进行标记处理,判断当前字符串在26个字母数组中,存在几个字母。
  • 通过位运算和移位的方式,不断获取到字符串中的字符,并进行标记到数组中。

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

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

相关文章

Tenable 利用 AI 升级漏洞评级系统,提升风险优先级排序能力

网络安全公司 Tenable Holdings Inc. 今日宣布对其漏洞优先级评级系统&#xff08;Vulnerability Priority Rating&#xff0c;VPR&#xff09;进行人工智能驱动的升级&#xff0c;旨在帮助机构更准确地识别和应对最具威胁性的漏洞。从60%到1.6%的精准聚焦Tenable VPR 系统于20…

安全插座项目规划书

安全插座项目规划书 一、项目概述 本项目旨在设计并开发一款安全插座&#xff0c;通过集成多种安全保护功能&#xff0c;有效预防因电气故障引发的安全问题&#xff0c;如过载、短路、漏电等&#xff0c;为用户提供更加可靠的用电环境。 二、技术架构 &#xff08;一&#xff0…

Logcat日志分析

1. AndroidRuntime关键字&#xff08;跟整个系统代码相关&#xff09; 一、AndroidRuntime的核心作用 AndroidRuntime是Android系统负责启动和运行应用程序的核心组件&#xff0c;当应用因未处理的异常&#xff08;如空指针、数组越界等&#xff09;导致崩溃时&#xff0c;Andr…

Apache Ranger 权限管理

编译 mvn install package -DskipTests -Dfast -Drat.skiptrue -Dmaven.test.skiptrue -Dcheckstyle.skiptrue -Denforcer.skiptrueinstall.properties PYTHON_COMMAND_INVOKERpython#DB_FLAVORMYSQL|ORACLE|POSTGRES|MSSQL|SQLA DB_FLAVORMYSQL ## # Location of DB client l…

tailscale+GitLab

1. 查看当前 LFS 的远程地址 bash 复制 git lfs env | grep Endpoint 你会看到类似&#xff1a; Endpointhttp://192.168.3.36/makeup/classicparking.git/info/lfs (authbasic) 2. 修改 LFS 的远程地址 使用以下命令将 LFS 的地址改为 http://100.125.163.56&#xff1…

微信通话自动录音器

—————【下 载 地 址】——————— 【​本章下载一】&#xff1a;https://pan.xunlei.com/s/VOVvLpQuRxYadClkxTGwO2OnA1?pwdvind# 【​本章下载二】&#xff1a;https://pan.xunlei.com/s/VOVvLpQuRxYadClkxTGwO2OnA1?pwdvind# 【百款黑科技】&#xff1a;https://uc…

05.原型模式:从影分身术到细胞分裂的编程艺术

目录序幕&#xff1a;当复制对象成为战略需求一、原型工厂的核心装备库1.1 Java原生的浅克隆术二、深度克隆的炼金法则2.1 手工克隆大法&#xff08;硬核派&#xff09;2.2 序列化克隆术&#xff08;魔法派&#xff09;三、原型模式的工业级装配3.1 原型注册管理局3.2 Spring框…

[NLP]如何在 Synopsys VCS 仿真脚本中处理多个 UPF 文件的加载

如何在 Synopsys VCS 仿真脚本中处理多个 UPF 文件的加载 摘要:我将详细解释在 Synopsys VCS(VCS)模拟脚本中如何处理多个 UPF 文件的加载,包括原理、命令选项、示例脚本以及注意事项。这基于 VCS 的 native low power verification 支持(IEEE 1801 UPF 标准)。如…

DNF: Decouple and Feedback Network for Seeing in the Dark

DNF&#xff1a;用于暗光视觉的解耦与反馈网络 摘要 RAW 数据的独特属性在低光照图像增强方面展现出巨大潜力。然而&#xff0c;现有架构在单阶段和多阶段方法中的固有局限性限制了其性能。跨两个不同域&#xff08;噪声到干净和 RAW 到 sRGB&#xff09;的混合映射&#xff0c…

论文精读《Frequency domain watermarking: An overview》

1. 数字水印技术基础概念与发展背景 数字水印技术作为信息隐藏领域的核心分支,其发展历程可以追溯到20世纪90年代中期计算机网络和信息技术的快速发展时期。随着大量版权作品以数字文件形式存在,电子出版逐渐普及,传统的版权保护方法面临前所未有的挑战。数字水印技术应运而…

北斗短报文兜底、5G-A增强:AORO P1100三防平板构建应急通信网络

公网中断的灾区现场&#xff0c;泥石流阻断了最后一条光缆。一支救援队却在废墟间有序穿行&#xff0c;队长手中的三防平板正闪烁着北斗卫星信号&#xff0c;定位坐标与伤亡信息化作一行行短报文&#xff0c;穿透通信孤岛直达指挥中心。这是AORO P1100三防平板搭载的北斗短报文…

Java排序算法之<冒泡排序>

目录 1、冒泡排序介绍 2、算法步骤 3、Java 实现&#xff08;带优化&#xff09; 4、算法复杂度分析 5、优点与缺点 前言 排序算法的“进化路线”&#xff1a; 冒泡排序 → 选择排序 → 插入排序 → 希尔排序 → 快速排序 → 归并排序 → 堆排序↓Java 内置排序&#xff…

生活毫无头绪就毫无头绪吧(7.24)

最近好长一段时间没有记录了明显感觉自己陷入了混乱中作息规律&#xff0c;专注力&#xff0c;心流&#xff0c;营养的饭菜如今下笔也没有什么头绪&#xff0c;前些日子本有感想但是又疲于记录&#xff0c;忘了许许多多最近在写论文&#xff0c;但尝试了游泳——蛙泳感觉太神奇…

vulhub-master 靶场Apache(httpd)漏洞

apache_parsing_vulnerability 漏洞原理在Apache1.x/2.x中Apache 解析⽂件的规则是从右到左开始判断解析,如果后缀名为不可识别⽂件解析,就再往左判断。如 1.php.xxxxx&#xff0c;Apache会试图识别你的代码&#xff0c;从右往左一个一个试。漏洞攻略参加一个1.php.jpg文件&…

Python 数据分析(一):NumPy 基础知识

目录 1. 简介2. 使用 2.1 ndarray2.2 数据类型2.3 索引与切片2.4 副本与视图2.5 轴的概念2.6 基本运算2.7 常用操作 1. 简介 NumPy&#xff08;Numerical Python&#xff09;是一个开源的 Python 科学计算扩展库&#xff0c;主要用来处理任意维度数组与矩阵&#xff0c;通常…

编程与数学 03-002 计算机网络 04_数据链路层功能

编程与数学 03-002 计算机网络 04_数据链路层功能一、数据链路层的基本任务&#xff08;一&#xff09;封装成帧&#xff08;二&#xff09;差错控制&#xff08;三&#xff09;流量控制二、差错检测与纠正方法&#xff08;一&#xff09;常用的差错检测码&#xff08;二&#…

latex中既控制列内容位置又控制列宽,使用>{\centering\arraybackslash}p{0.85cm}

示例&#xff1a;\usepackage{array} % 为 >{...} 修饰符提供支持\begin{table*}[ht!]\centering \begin{tabular}{p{2.8cm} >{\centering\arraybackslash}p{0.85cm} >{\centering\arraybackslash}p{0.85cm} >{\centering\arraybackslash}p{0.85cm} >{\ce…

医疗数据挖掘Python机器学习案例

1. 医疗数据挖掘概述 医疗数据挖掘是从大量的医疗数据中提取有价值信息和知识的过程&#xff0c;旨在辅助医疗决策、疾病预测、治疗方案优化等。随着医疗信息化的发展&#xff0c;电子病历、医疗影像、基因数据等多源异构数据不断积累&#xff0c;为医疗数据挖掘提供了丰富的素…

人工智能概述

&#x1f31f; 欢迎来到AI奇妙世界&#xff01; &#x1f31f; 亲爱的开发者朋友们&#xff0c;大家好&#xff01;&#x1f44b; 我是人工智能领域的探索者与分享者&#xff0c;很高兴在CSDN与你们相遇&#xff01;&#x1f389; 在这里&#xff0c;我将持续输出AI前沿技术、实…

C++性能优化擂台技术文章大纲

引言性能优化在C开发中的重要性擂台赛形式的优势&#xff1a;激发创意&#xff0c;展示不同优化技巧目标读者&#xff1a;中高级C开发者擂台赛规则设计统一基准测试环境&#xff08;硬件、编译器、优化标志&#xff09;参赛代码需通过功能正确性验证性能指标&#xff1a;执行时…