刷題筆記--串聯所有單詞的子串

題目:

1、我的寫法(超時)

從題面自然想到先用回溯算法把words的全排列先算出來,然后遍歷字符串s一次將符合條件的位置加入結果

全排列計算所有可能字符串算法寫法:

這是一個模板用于所有全排列算法的情況,本質思想是回溯。四個參數:words代表候選單詞數組,path代表已經選過的路徑,used代表當前元素有沒有使用過,result代表結果這里用了set去重

在每次回溯開始前先判斷,當前路徑有沒有包含所有候選單詞,如果都包含了的話就加入結果。

從當前path開始算,嘗試所有可能性,把沒用到的元素加入path遞歸,然后恢復數據開始下一次回溯

這是我在外層調用的方法,最后顯示超時了,超時原因在于當words長度過長時,遞歸回溯的方法復雜度不好控制,過于耗時

完整代碼:

class Solution {

? ? public List<Integer> findSubstring(String s, String[] words) {

? ? ? ? //全排列找出words能拼接成的所有字符串

? ? ? ? Set<String> concatStr = new HashSet<>();

? ? ? ? boolean[] used = new boolean[words.length];

? ? ? ? backTrack(words, new ArrayList<>(), used, concatStr);

? ? ? ? //遍歷字符串s,與所有可能的拼接結果對比,找到符合的結果

? ? ? ? int wordLen = 0;

? ? ? ? List<Integer> result = new ArrayList<>();

? ? ? ? for(int i = 0; i < words.length; i++) {

? ? ? ? ? ? wordLen += words[i].length();

? ? ? ? }

? ? ? ? for(int i = 0; i <= s.length() - wordLen; i++) {

? ? ? ? ? ? if(concatStr.contains(s.substring(i, i + wordLen))) {

? ? ? ? ? ? ? ?result.add(i);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return result;

? ? }

? ? private void backTrack(String[] words, List<String> path, boolean[] used, Set<String> result) {

? ? ? ? if(path.size() == words.length) {

? ? ? ? ? ? result.add(String.join("", path));

? ? ? ? }

? ? ? ? for(int i = 0; i < words.length; i++) {

? ? ? ? ? ? if(used[i] == false) {

? ? ? ? ? ? ? ? //如果沒有被用過加入path中

? ? ? ? ? ? ? ? used[i] = true;

? ? ? ? ? ? ? ? path.add(words[i]);

? ? ? ? ? ? ? ? //遞歸回溯

? ? ? ? ? ? ? ? backTrack(words, path, used, result);

? ? ? ? ? ? ? ? //撤銷操作,去掉最后一個元素并標記為未使用

? ? ? ? ? ? ? ? used[i] = false;

? ? ? ? ? ? ? ? path.remove(path.size() - 1);

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

2、官方解法

不需要遞歸回溯,用到了異位字符串思想

官解的思路類似于找到字符串中的字母異位詞,只不過它從之前的字母異位變成了字符串異位。注意,體面中words每個單詞的長度都是相等的,所以我們是可以等長的去劃分子串的,這樣劃分之后用哈希表differ去劃分。

遍歷一遍數組,從0開始,直到最后無法滿足長度為止。每次循環,都初始化一個哈希表用來記錄劃分后的單詞出現頻率和words的誤差,等同于之前字符串中找到字母異位詞的做法,只不過這里不再是字母而是一個個長度相等的字符串

完整代碼:

class Solution {

? ? public List<Integer> findSubstring(String s, String[] words) {

? ? ? ? List<Integer> res = new ArrayList<Integer>();

? ? ? ? int m = words.length, n = words[0].length(), ls = s.length();

? ? ? ? for (int i = 0; i < n; i++) {

? ? ? ? ? ? if (i + m * n > ls) {

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? ? ? Map<String, Integer> differ = new HashMap<String, Integer>();

? ? ? ? ? ? for (int j = 0; j < m; j++) {

? ? ? ? ? ? ? ? String word = s.substring(i + j * n, i + (j + 1) * n);

? ? ? ? ? ? ? ? differ.put(word, differ.getOrDefault(word, 0) + 1);

? ? ? ? ? ? }

? ? ? ? ? ? for (String word : words) {

? ? ? ? ? ? ? ? differ.put(word, differ.getOrDefault(word, 0) - 1);

? ? ? ? ? ? ? ? if (differ.get(word) == 0) {

? ? ? ? ? ? ? ? ? ? differ.remove(word);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? for (int start = i; start < ls - m * n + 1; start += n) {

? ? ? ? ? ? ? ? if (start != i) {

? ? ? ? ? ? ? ? ? ? String word = s.substring(start + (m - 1) * n, start + m * n);

? ? ? ? ? ? ? ? ? ? differ.put(word, differ.getOrDefault(word, 0) + 1);

? ? ? ? ? ? ? ? ? ? if (differ.get(word) == 0) {

? ? ? ? ? ? ? ? ? ? ? ? differ.remove(word);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? word = s.substring(start - n, start);

? ? ? ? ? ? ? ? ? ? differ.put(word, differ.getOrDefault(word, 0) - 1);

? ? ? ? ? ? ? ? ? ? if (differ.get(word) == 0) {

? ? ? ? ? ? ? ? ? ? ? ? differ.remove(word);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (differ.isEmpty()) {

? ? ? ? ? ? ? ? ? ? res.add(start);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return res;

? ? }

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87712.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87712.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87712.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

操作系統【1】【硬件結構】【操作系統結構】

一、CPU如何執行程序&#xff1f; 提綱 圖靈機工作方式馮諾依曼模型線路位寬CPU位寬程序執行基本過程執行具體過程 1. 圖靈機工作方式 圖靈機可以視作“一臺帶規則的自動草稿機” 圖靈機基本組成&#xff1a; 紙帶&#xff08;內存&#xff09;&#xff1a;連續格子組成&…

SQLite與MySQL:嵌入式與客戶端-服務器數據庫的權衡

SQLite與MySQL&#xff1a;嵌入式與客戶端-服務器數據庫的權衡 在開發應用程序時&#xff0c;數據庫選擇是一個至關重要的決策&#xff0c;它會影響應用的性能、可擴展性、部署難度和維護成本。SQLite和MySQL是兩種廣泛使用的關系型數據庫管理系統&#xff0c;它們各自針對不同…

CppCon 2018 學習:Smart References

“強類型別名”&#xff08;strong typedefs&#xff09; 的動機和實現&#xff0c;配合一個簡單例子說明&#xff1a; 動機&#xff08;Motivation&#xff09; 用 using filename_t string; 和 using url_t string; 來區分不同的字符串類型&#xff08;比如文件名和網址&…

高性能高準確度的CPU電壓與溫度監測軟件HWInfo

&#x1f5a5;? 一、軟件概述 Windows版&#xff1a;圖形化界面&#xff0c;支持實時監控&#xff08;溫度、電壓、風扇轉速等&#xff09;、基準測試及報告生成&#xff0c;兼容Windows XP至Windows 11系統。Linux版&#xff1a;命令行工具&#xff0c;由openSUSE社區維護&a…

H3C WA6322 AP版本升級

1、查看當前版本&#xff1a;R2444P01 2、官網下載升級文件&#xff1a; WA6300系列版本說明H3C WA6300系列(適用于WA6330、 WA6322、WA6320H、WA6320、 WTU630H、WTU630、WA6330-LI、WA6320-C、WA6320-D、WA6320H-LI、WA6338、WA6322H、WTU632H-IOT、WAP922E、WAP923、WA6320…

用 YOLOv8 + DeepSORT 實現目標檢測、追蹤與速度估算

【導讀】 目標檢測與追蹤技術是計算機視覺領域最熱門的應用之一&#xff0c;廣泛應用于自動駕駛、交通監控、安全防護等場景。今天我們將帶你一步步實現一個完整的項目&#xff0c;使用YOLOv8 DeepSORT實現目標檢測、追蹤與速度估算。>>更多資訊可加入CV技術群獲取了解…

Python實例題:基于 Python 的簡單聊天機器人

Python實例題 題目 基于 Python 的簡單聊天機器人 要求&#xff1a; 使用 Python 構建一個聊天機器人&#xff0c;支持以下功能&#xff1a; 基于規則的簡單問答系統關鍵詞匹配和意圖識別上下文記憶功能支持多輪對話可擴展的知識庫 使用tkinter構建圖形用戶界面。實現至少 …

相機:Camera原理講解(使用OpenGL+QT開發三維CAD)

相機為三維場景提供了靈活便捷的視角變換和交互能力&#xff0c;通過相機操作可以實現全方位、各角度的場景瀏覽。 怎樣在三維場景中引入相機&#xff0c;怎樣處理和實現視角的放縮、移動、旋轉&#xff1f;在視角旋轉時以指定目標為中心又該怎樣處理&#xff1f; 原文&#…

開源的虛擬電廠預測數據:資源、應用與挑戰

引言 虛擬電廠(Virtual Power Plant, VPP)是一種通過聚合分布式能源資源(如太陽能、風能、儲能系統、電動汽車和可控負荷)來優化電力系統運行的數字化能源管理平臺。準確的預測數據是虛擬電廠高效運行的關鍵,而開源數據為研究者和企業提供了低成本、高透明度的解決方案。…

IDE全家桶專用快捷鍵----------個人獨家分享!!

給大家分享一下我個人整理的快捷鍵&#xff0c;其中包含對電腦的操作&#xff0c;以及在編寫代碼時的操作&#x1f680;Window系列1 WindowsR 開啟運行對話框--->輸入cmd啟動黑窗口?2 WindowsE 快速打開我的電腦 ?3 WindowsL 電腦鎖屏 ?4 WindowsD 顯示/恢復桌面 ?5 Win…

人工智能概念:RNN中的基礎Encoder-Decoder框架

文章目錄一、序列&#xff08;Seq2Seq&#xff09;轉換的核心架構二、Encoder-Decoder框架基礎原理2.1 整體工作流程2.2 編碼器&#xff08;Encoder&#xff09;詳解2.3 解碼器&#xff08;Decoder&#xff09;工作機制與缺陷三、基礎框架的核心缺陷分析&#xff08;以"歡…

R 列表:深入解析與高效應用

R 列表&#xff1a;深入解析與高效應用 引言 在R語言中&#xff0c;列表&#xff08;List&#xff09;是一種非常重要的數據結構&#xff0c;它允許我們將不同類型的數據組合在一起。列表在數據分析和統計建模中扮演著至關重要的角色。本文將深入探討R列表的概念、創建方法、…

uniapp 國密sm2加密

1. uniapp 國密sm2加密 在uniapp中使用國密SM2算法進行加密解密&#xff0c;你可以通過安裝第三方庫miniprogram-sm-crypto來實現。這個庫提供了SM2、SM3和SM4算法的實現&#xff0c;可以在小程序和uniapp項目中使用。 1.1. 安裝miniprogram-sm-crypto 首先&#xff0c;你需要…

07_持續集成與部署:DevOps的核心引擎

07_持續集成與部署:DevOps的核心引擎 引言 在快速迭代的軟件開發時代,持續集成(CI)與持續部署(CD)已成為企業提升競爭力的關鍵。通過自動化構建、測試和部署流程,CI/CD能夠顯著縮短交付周期,提高軟件質量,降低發布風險。本文將深入探討CI/CD的核心理念、實施路徑與最…

電腦休眠設置

Dont Sleep的意思就是“不要睡覺”&#xff0c;用在電腦里就是“阻止休眠”的意思。但這款軟件其實有“阻止休眠”和“允許休眠”兩個功能。 阻止休眠時可以選擇事件&#xff0c;是計時器、電池、CPU、網絡這幾個事件進行觸發阻止休假的功能。 允許休眠也可以根據自己的需求進行…

藍牙墨水屏上位機學習(3)

main.js中sendimg()函數學習&#xff0c;對應發送圖片按鈕函數代碼如下&#xff1a;async function sendimg() {const canvasSize document.getElementById(canvasSize).value;const ditherMode document.getElementById(ditherMode).value;const epdDriverSelect document.…

Linux應用基礎

1. 基礎概念 1.1 系統調用 系統調用實際上是Linux內核為上層應用程序提供的API接口&#xff0c;方便應用程序進行調用&#xff0c;類似于SVC。 1.2 庫函數 庫函數是應用層里邊的東西&#xff0c;在系統調用的上層&#xff0c;通常以動態庫文件&#xff08;.so&#xff09;形式…

【時間序列數據處理的噩夢與救贖:一次復雜數據可視化問題的深度復盤】

時間序列數據處理的噩夢與救贖&#xff1a;一次復雜數據可視化問題的深度復盤 創建時間: 2025/7/3 技術棧: Vue 3 TypeScript UniApp ECharts 問題級別: &#x1f534; 系統性架構問題 &#x1f3af; 引言&#xff1a;當簡單需求變成技術噩夢 “老哥&#xff0c;這個圖表時…

Redis--黑馬點評--基于stream消息隊列的秒殺優化業務詳解

基于redis的stream結構作為消息隊列&#xff0c;實現異步秒殺下單 需求&#xff1a; 創建一個Stream類型的消息隊列&#xff0c;名為stream.oreders 修改之前的秒殺下單Lua腳本&#xff0c;在認定有搶夠資格后&#xff0c;直接向stream.orders中添加消息&#xff0c;內容包括…

Zephyr RTOS 防止中斷影響數據寫入

目錄 概述 1 中斷保護核心策略 1.1 中斷鎖定/解鎖 (IRQ Locking) 1.2 自旋鎖 (Spin Locks) 2 高級保護技術 2.1 雙重緩沖技術 2.2 RCU (Read-Copy-Update) 模式 3 中斷安全數據寫入模式 3.1 FIFO隊列保護 3.2 原子操作保護 4 性能優化策略 4.1 分區數據保護 4.2 中斷…