【算法專題訓練】05、最大單詞長度乘積

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;執行時…