【LeetCode 熱題 100】438. 找到字符串中所有字母異位詞——(解法二)定長滑動窗口+數組

Problem: 438. 找到字符串中所有字母異位詞
題目:給定兩個字符串 s 和 p,找到 s 中所有 p 的 異位詞 的子串,返回這些子串的起始索引。不考慮答案輸出的順序。

【LeetCode 熱題 100】438. 找到字符串中所有字母異位詞——(解法一)定長滑動窗口+哈希表
【LeetCode 熱題 100】438. 找到字符串中所有字母異位詞——(解法三)不定長滑動窗口+數組

整體思路

這段代碼同樣旨在解決 “在一個字符串 s 中找出所有模式串 p 的異位詞” 的問題。與上一個使用 HashMap 的版本相比,此版本采用了 固定大小的數組 作為頻率計數的工具,這是一種針對特定字符集(此處為小寫英文字母)的常見優化。

算法的核心思路依然是 滑動窗口,但具體實現細節有所不同:

  1. 數據結構選擇與預處理

    • 該實現選擇了兩個大小為 26 的整型數組 cntPcntS 來分別存儲模式串 p 和當前滑動窗口的字符頻率。
    • 前提與優勢:這個選擇基于一個重要假設——輸入字符串 sp 只包含小寫英文字母。利用 char - 'a' 的技巧,可以將每個字符映射到數組的 0-25 索引上,這比 HashMap 更快且內存占用更低。
    • 首先,代碼遍歷模式串 p,將其字符頻率統計到 cntP 數組中。這個數組是固定不變的“目標”。
  2. 一體化的滑動窗口遍歷

    • 與上一個版本先初始化窗口再滑動的兩步法不同,此版本將窗口的初始化、擴張、校驗和收縮整合在一個 for 循環中。
    • 循環由一個 right 指針驅動,從頭到尾遍歷主串 s
    • 窗口擴張:在每次迭代中,首先將 right 指針指向的字符計入窗口頻率數組 cntS
    • 窗口形成與校驗:通過 left = right - m + 1 計算出窗口的左邊界。
      • if (left < 0) 這個條件用于處理窗口還未形成完整大小(長度為 m)的初始階段。在窗口大小不足 m 時,只進行擴張,不進行比較和收縮。
      • left >= 0 時,說明窗口已經達到了 m 的長度。此時,使用 Arrays.equals(cntP, cntS) 來比較兩個頻率數組。Arrays.equals 會逐一比較數組中的每個元素,如果所有元素都相等,則證明當前窗口內的子串是 p 的一個異位詞,將其起始索引 left 加入結果列表。
    • 窗口收縮:在完成校驗后(無論是否匹配),將 left 指針指向的字符從窗口中移除(即在 cntS 中將其頻率減一),為下一次迭代做準備。這樣,窗口就整體向右平移了一格。
  3. 返回結果

    • 循環結束后,返回包含所有起始索引的結果列表 ans

這種一體化的實現方式代碼更緊湊,邏輯流程非常清晰:每一步都“加一個右邊的,(可能的話)比一下,再減一個左邊的”。

完整代碼

class Solution {/*** 在字符串 s 中查找 p 的所有異位詞的起始索引。* 此版本使用數組進行頻率統計,優化了性能。* @param s 主字符串 (假定只包含小寫字母)* @param p 模式字符串 (假定只包含小寫字母)* @return 一個包含所有匹配起始索引的列表*/public List<Integer> findAnagrams(String s, String p) {// ans 用于存儲結果,即所有異位詞的起始索引List<Integer> ans = new ArrayList<>();// n 是主串 s 的長度,m 是模式串 p 的長度int n = s.length();int m = p.length();// 如果主串比模式串還短,直接返回空列表if (n < m) {return ans;}// cntS: 存儲當前滑動窗口內子串的字符頻率// cntP: 存儲模式串 p 的字符頻率// 使用大小為 26 的數組,因為題目隱含了輸入為小寫英文字母int[] cntS = new int[26];int[] cntP = new int[26];// 步驟 1: 統計模式串 p 中每個字符的出現次數for (char c : p.toCharArray()) {// 'c' - 'a' 將字符映射到 0-25 的索引cntP[c - 'a']++;}// 步驟 2: 滑動窗口遍歷主串 sfor (int right = 0; right < n; right++) {// a. 窗口擴張:將右邊界字符加入窗口的頻率統計中cntS[s.charAt(right) - 'a']++;// 計算當前窗口的左邊界索引int left = right - m + 1;// 判斷窗口是否已形成。當 left < 0 時,窗口大小不足 m,跳過比較和收縮步驟。if (left < 0) {continue;}// b. 窗口內校驗:當窗口大小正好為 m 時,比較窗口和模式串的頻率數組// Arrays.equals() 逐元素比較兩個數組,如果完全相同則返回 trueif (Arrays.equals(cntP, cntS)) {// 如果是異位詞,將當前窗口的起始索引 left 加入結果列表ans.add(left);}// c. 窗口收縮:將即將移出窗口的左邊界字符的頻率減一cntS[s.charAt(left) - 'a']--;}// 返回最終的結果列表return ans;}
}

時空復雜度

時間復雜度:O(N + M)
  1. 模式串頻率統計for (char c : p.toCharArray()) 循環遍歷模式串 p 一次。設 p 的長度為 M,此步驟時間復雜度為 O(M)
  2. 滑動窗口遍歷for (int right = 0; right < n; right++) 循環遍歷主串 s 一次。設 s 的長度為 N,此循環執行 N 次。
    • 在循環內部:
      • 數組的讀寫操作(cntS[...]++cntS[...]--)是 O(1) 的。
      • Arrays.equals(cntP, cntS) 操作需要比較兩個數組中的所有元素。由于數組大小是固定的 26,所以比較的次數也是常數 26。因此,該操作的時間復雜度為 O(26),即 O(1)
    • 所以,整個循環的時間復雜度是 N 次 O(1) 操作,總計為 O(N)

綜合分析
總時間復雜度 = 預處理 p 的時間 + 遍歷 s 的時間 = O(M) + O(N) = O(N + M)
由于通常 N 是遠大于 M 的,所以有時也近似地稱為 O(N),但 O(N + M) 是更精確的表述。

空間復雜度:O(k) 或 O(1)
  1. 主要存儲開銷:算法使用了兩個整型數組 cntScntP
    • 每個數組的大小都是 26,這是一個固定的常數,不隨輸入字符串 sp 的長度變化而變化。
    • k 在這里代表字符集的大小,即 26。
  2. 其他變量n, m, right, left 等變量占用的是常數空間 O(1)。
  3. 結果列表ans 列表用于存儲輸出,其空間不計入輔助空間復雜度。

綜合分析
算法所需的額外輔助空間主要由兩個頻率數組決定。由于數組大小是固定的,所以空間復雜度是 O(k),其中 k=26。因為 k 是一個常數,所以也可以表述為 O(1)。這表示算法占用的額外內存是一個常數,非常高效。

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

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

相關文章

PAC 學習框架:機器學習的可靠性工程

PAC&#xff08;Probably Approximately Correct&#xff09; 是機器學習理論的核心框架&#xff0c;用于量化學習算法的可靠性。它回答了一個關鍵問題&#xff1a; “需要多少訓練樣本&#xff0c;才能以較高概率學到一個近似正確的模型&#xff1f;” 一、PAC 名稱拆解 術語…

嵌入式C語言數組:數組/字符數組

1. 數組 1.1 一維數組 數組是一串連續的地址&#xff1b; 數組名是地址常量&#xff0c;代表數組的起始地址&#xff1b; sizeof&#xff08;數組名&#xff09; 可得出數組的總內存空間&#xff1b; C 語言對數組不做越界檢查&#xff0c;使用時應注意&#xff1b; 數組不…

變長字節的數字表示法vb224

開始 數字有大有小&#xff0c;用多少字節表示呢&#xff1f; 本文描述的方案&#xff0c;采用變化的長度。vb是varying bytes的意思&#xff0c;224是表示它特征的一個數。 第一版&#xff1a; 每個字節8比特&#xff0c;最高的1比特用來表示“是否連續”&#xff0c;0表示…

ByteMD+CozeAPI+Coze平臺Agent+Next搭建AI輔助博客撰寫平臺(邏輯清楚,推薦!)

背景&#xff1a; 現在主流的博客平臺AI接入不夠完善&#xff0c;如CSDN接入的AI助手不支持多模態數據的交互、稀土掘金的編輯器AI功能似乎還沒能很好接入&#xff08;哈哈哈&#xff0c;似乎在考慮布局什么&#xff1f;&#xff09; 痛點分析&#xff1a; 用戶常常以截圖的形式…

【數據標注師】關鍵詞標注

目錄 一、 **理解關鍵詞標注的核心邏輯**1. **三大標注原則**2. **關鍵詞類型體系** 二、 **四階訓練體系**? **階段1&#xff1a;基礎規則內化**? **階段2&#xff1a;語義濃縮訓練**? **階段3&#xff1a;場景化標注策略**? **階段4&#xff1a;工具效率提升** 三、 **五…

for each循環語句

for each循環語句 for each.....nextFor Each 的案例 for each…next 1、循環對象合集 worksheets workbooks range range("區域")selection (選中的區域)usedrange或者currentregion 返回的單元格區域格式&#xff1a; for each 變量名 in 對象集合(范圍)循環內容…

基于LQR控制器的六自由度四旋翼無人機模型simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序 4.系統原理簡介 5.參考文獻 6.完整工程文件 1.課題概述 四旋翼無人機因其結構簡單、機動性強和成本低廉等特點&#xff0c;在航拍測繪、物流運輸、災害救援等領域得到廣泛應用。六自由度&#xff08;3維平移3維旋轉&#xff0…

vftp centos 離線部署

install_ftp_offline.sh vsftpd-3.0.2-28.el7.x86_64.rpm #!/bin/bash# 一鍵安裝配置vsftpd腳本&#xff08;開放根目錄&#xff0c;禁用chroot&#xff09;# 安裝vsftpd RPM包 echo "正在安裝vsftpd..." rpm -ivh vsftpd-3.0.2-28.el7.x86_64.rpm if [ $? -ne 0 …

【數據標注】事件標注1

目錄 **一、 深入理解事件標注的核心概念****二、 系統學習&#xff1a;從理論到實踐****1. 吃透標注指南****2. 語言學基礎補充****3. 事件結構解析訓練** **三、 分階段實踐&#xff1a;從簡單到復雜****階段1&#xff1a;基礎標注訓練****階段2&#xff1a;進階挑戰****階段…

在 Ansys Electronics Desktop 中啟用額外的 CPU 內核和 GPU

Ansys Electronics Desktop (AEDT) 可以通過利用多個 CPU 內核和 GPU 加速來顯著縮短仿真時間。但是,啟用其他計算資源除了基本求解器許可證外,還需要適當的高性能計算 (HPC) 許可證。 默認情況下,基本許可證最多允許使用 4 個內核,而無需任何其他 HPC 許可。借助 Ans…

R語言機器學習算法實戰系列(二十六)基于tidymodels的XGBoost二分類器全流程實戰

禁止商業或二改轉載,僅供自學使用,侵權必究,如需截取部分內容請后臺聯系作者! 文章目錄 介紹加載R包數據準備數據探索轉換因子查看屬性相關性配對圖PCA 可視化缺失值、異常值處理 & 特征標準數據分割構建模型與調參模型評估模型可解釋性(變量重要性、SHAP、DALEX)變量…

零基礎langchain實戰一:模型、提示詞和解析器

一&#xff0c;使用python調取大模型api 1&#xff0c;獲取api_key 獲取api_key 在各個大模型的官網中獲取。 2&#xff0c;設置api_key 方式一&#xff1a; 在系統環境中可直接執行python代碼&#xff1a;這里以deepseek為例 import os os.environ["DEEPSEEK_API_…

Pytorch分布式通訊為什么要求Tensor連續(Contiguous)

參考資料&#xff1a; https://github.com/pytorch/pytorch/issues/73515 https://www.cnblogs.com/X1OO/articles/18171700 由于業務原因&#xff0c;需要在Pytorch代碼中使用分布式通訊來把計算負載平均到多張顯卡上。在無數次確認我的業務代碼沒問題之后&#xff0c;我開始把…

關于前端頁面上傳圖片檢測

依賴于前文&#xff0c;linux系統上部署yolo識別圖片,遠程宿主機訪問docker全流程(https://blog.csdn.net/yanzhuang521967/article/details/148777650?spm1001.2014.3001.5501) fastapi把端口暴露出來 后端代碼 from fastapi import FastAPI, UploadFile, File, HTTPExcep…

第十三章---軟件工程過程管理

僅供參考 文章目錄 一、Gantt圖是做什么的。二、軟件配置的概念 一、Gantt圖是做什么的。 Gantt 圖&#xff08;甘特圖&#xff09;是軟件項目管理中用于進度安排和可視化管理的重要工具&#xff0c;主要用于展示任務的時間安排、進度狀態及任務之間的依賴關系 Gantt 圖是一種…

多模態大語言模型arxiv論文略讀(140)

SemiHVision: Enhancing Medical Multimodal Models with a Semi-Human Annotated Dataset and Fine-Tuned Instruction Generation ?? 論文標題&#xff1a;SemiHVision: Enhancing Medical Multimodal Models with a Semi-Human Annotated Dataset and Fine-Tuned Instruc…

模型預測控制專題:無差拍預測電流控制

前言&#xff1a; 為了進一步深入探索電機控制這個領域&#xff0c;找到了一些志同道合的同學一起來進行知識的分享。最近群里投票后續更新內容&#xff0c;票數最多的方向就是模型預測控制&#xff1b;無論這個方向目前是否還是很火&#xff0c;至少應大家需求&#xff0c;工…

Youtube雙塔模型

1. 引言 在大規模推薦系統中&#xff0c;如何從海量候選物品中高效檢索出用戶可能感興趣的物品是一個關鍵問題。傳統的矩陣分解方法在處理稀疏數據和長尾分布時面臨挑戰。本文介紹了一種基于雙塔神經網絡的建模框架&#xff0c;通過采樣偏差校正技術提升推薦質量&#xff0c;并…

.net8創建tcp服務接收數據通過websocket廣播

注冊TCP服務器 注冊WebSocket中間件 using System.Net; using System.Net.Sockets; using System.Text; using System.Text.Json; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.AspNet…

閱讀服務使用示例(HarmonyOS Reader Kit)

閱讀服務使用示例&#xff08;HarmonyOS Reader Kit&#xff09; Reader Kit到底能干啥&#xff1f; 第一次搞電子書閱讀器&#xff0c;真以為就是“讀txt顯示出來”這么簡單&#xff0c;結果各種格式、排版、翻頁動效、目錄跳轉……全是坑。還好有Reader Kit&#xff0c;救了…