日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

leetcode 438. Find All Anagrams in a String | 438. 找到字符串中所有字母异位词(Java)

發布時間:2024/2/28 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 438. Find All Anagrams in a String | 438. 找到字符串中所有字母异位词(Java) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

https://leetcode.com/problems/find-all-anagrams-in-a-string/

題解

方法1:嘗試構造一種“與順序無關的哈希”

思考

是否可以構造順序無關的哈希?例如,我們希望 aabc 與 bcaa 的哈希值相同。

思路

找到一種映射方式,使得在保證每一個字母都出現在 set 中的情況下,讓不同字母具有不同的貢獻度,計算每個字母的貢獻度求 sum,從而實現“不同數量的字母組成的不同序列具有唯一 sum,相同數量的字母組合具有相同 sum,結果與順序無關”。

結果

上述“映射方式”可以被證明是不存在的。
我仍然用代碼實現了一遍,沒想到 AC 了。方法有邏輯問題,但是通過了所有的測試用例。
例如,a到z都包含在字符串中的情況下,只要找到 a+b = c+d,就是反例。

反例

a aac bcdefghijklmnopqrstuvwxyz
a bbb bcdefghijklmnopqrstuvwxyz
其中,中間部分的 a+a+c = b+b+b

證偽

以下步驟可以證明 一定存在反例

class Solution {public List<Integer> findAnagrams(String s, String p) {int target = 0;Set<Character> set = new HashSet<>();for (int i = 0; i < p.length(); i++) {target += Math.pow(2, p.charAt(i) - 'a');set.add(p.charAt(i));}ArrayList<Integer> list = new ArrayList<>();if (s.length() < p.length()) return list;int cur = 0;for (int i = 0; i < p.length(); i++) {cur += Math.pow(2, s.charAt(i) - 'a');}int i;for (i = 0; i < s.length() - p.length(); i++) {if (cur == target && set.contains(s.charAt(i))) list.add(i);cur -= Math.pow(2, s.charAt(i) - 'a');cur += Math.pow(2, s.charAt(i + p.length()) - 'a');}if (cur == target && set.contains(s.charAt(i))) list.add(i);return list;} }

手動構造的一個最簡單的反例:

方法2:

定義兩個數組:

  • target[26] 數組,統計目標窗口內每個字母的個數。
  • cur[26] 數組,統計當前滑窗內每個字母的個數。
  • dif 為兩數組之間個數不相等的字母總數。

先固定好窗口大小,每次雙指針前進1。

然后在固定窗口大小的基礎上,觀察操作前后的變化:

  • 如果操作前cur=dif,則dif+1
  • 如果操作后cur=dif,則dif-1
class Solution {public List<Integer> findAnagrams(String s, String p) {int[] target = new int[26];int dif = 0;for (int i = 0; i < p.length(); i++) {if (target[p.charAt(i) - 'a'] == 0) dif++;target[p.charAt(i) - 'a']++;}ArrayList<Integer> list = new ArrayList<>();if (s.length() < p.length()) return list;int[] cur = new int[26];for (int i = 0; i < p.length(); i++) {if (cur[s.charAt(i) - 'a'] == target[s.charAt(i) - 'a']) dif++; // 本來就相等cur[s.charAt(i) - 'a']++;if (cur[s.charAt(i) - 'a'] == target[s.charAt(i) - 'a']) dif--; // 加完之后相等了}int L;for (L = 0; L < s.length() - p.length(); L++) {if (dif == 0) list.add(L);int R = L + p.length();// 刪iif (cur[s.charAt(L) - 'a'] == target[s.charAt(L) - 'a']) dif++; // 本來就相等cur[s.charAt(L) - 'a']--;if (cur[s.charAt(L) - 'a'] == target[s.charAt(L) - 'a']) dif--; // 減完之后相等了// 加jif (cur[s.charAt(R) - 'a'] == target[s.charAt(R) - 'a']) dif++; // 本來就相等cur[s.charAt(R) - 'a']++;if (cur[s.charAt(R) - 'a'] == target[s.charAt(R) - 'a']) dif--; // 加完之后相等了}if (dif == 0) list.add(L);return list;} }

總結

以上是生活随笔為你收集整理的leetcode 438. Find All Anagrams in a String | 438. 找到字符串中所有字母异位词(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。