摘要:同時利用來存儲當(dāng)前結(jié)果值所在的起始下標(biāo)。然而,一旦出現(xiàn)重復(fù)值后,例如輸入的為,則無法判斷當(dāng)前重復(fù)值是否應(yīng)當(dāng)在結(jié)果集中。如果中的元素都被清空,則代表該子數(shù)組符合要求,即將起始下標(biāo)添加進入結(jié)果集。利用左右指針來限定最小子數(shù)組的范圍,即窗口大小。
題目要求
You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. For example, given: s: "barfoothefoobarman" words: ["foo", "bar"] You should return the indices: [0,9]. (order does not matter).
輸入一個字符串s和一個字符串?dāng)?shù)組words,其中words中的每個word的長度都相等。在字符串中找到所有子字符串的起始下標(biāo),只要該子字符串滿足words中所有單詞的連接結(jié)果(順序無關(guān))
思路一:map中存儲word和對應(yīng)的下標(biāo)(無法解決重復(fù)問題)在思路一中,我利用HashMap
代碼如下:
public List思路二 :map中存儲word和重復(fù)數(shù)量findSubstring(String s, String[] words) { List result = new ArrayList (); if(words.length == 0){ return result; } int wordLength = words[0].length(); int allWordsLength = words.length; Map wordMap = new HashMap (); for(int j = 0 ; j =start){ start = key + wordLength; //長度等于所有長度 }else if(i-start == wordLength*(allWordsLength-1)){ result.add(start); start+=wordLength; } wordMap.replace(current, i); i+=wordLength; continue; } i++; start = i; } return result; }
既然words中會有重復(fù)值,就想到利用map中來存儲word和其數(shù)量來判斷當(dāng)前下標(biāo)下的子數(shù)組中是否包含了map中所有的元素。如果map中的元素都被清空,則代表該子數(shù)組符合要求,即將起始下標(biāo)添加進入結(jié)果集。
該方法有一個缺陷在于,每一次移動起始下標(biāo),都要重新初始化一個map的副本。而在很多情況下,該副本可能根本就沒有發(fā)生改變。這樣的內(nèi)存利用率太低了,影響程序的效率。
public ListfindSubstring2(String s, String[] words) { List result = new ArrayList (); if(words.length == 0){ return result; } int wordLength = words[0].length(); int allWordsLength = words.length; Map wordMap = new HashMap (); for(int j = 0 ; j copy = new HashMap (wordMap); for(int i=start ; i 思路三 :minimum-window-substring 該思路是我借鑒了一個solution中的回答。minimum-window-substring是指,在尋找到所有元素都被包含進去的最小子數(shù)組中,判斷是否滿足目標(biāo)要求。利用左右指針來限定最小子數(shù)組的范圍,即窗口大小。同時左右指針每次都按照固定長度右移,以便尋找到下一個最小子數(shù)組。具體情況請參考代碼中的注釋。
public ListfindSubstring3(String s, String[] words) { //N為字符串長度 int N = s.length(); //結(jié)果集,長度必定不超過字符串長度 List indexes = new ArrayList (s.length()); if (words.length == 0) { return indexes; } //M為單個單詞的長度 int M = words[0].length(); //如果所有單詞連接之后的長度超過字符串長度,則返回空結(jié)果集 if (N < M * words.length) { return indexes; } //last 字符串中最后一個可以作為單詞起始點的下標(biāo) int last = N - M + 1; //map存儲word和其在table[0]中對應(yīng)的下標(biāo) Map mapping = new HashMap (words.length); //table[0]存儲每個word出現(xiàn)的真實次數(shù),table[1]存儲每個word目前為止出現(xiàn)的統(tǒng)計次數(shù) int [][] table = new int[2][words.length]; //failures存儲words中不重復(fù)值的總數(shù),例如["good","bad","good","bad"],failures=2 int failures = 0, index = 0; for (int i = 0; i < words.length; ++i) { Integer mapped = mapping.get(words[i]); if (mapped == null) { ++failures; mapping.put(words[i], index); mapped = index++; } ++table[0][mapped]; } //遍歷字符串s,判斷字符串當(dāng)前下標(biāo)后是否存在words中的單詞,如果存在,則填入table中的下標(biāo),不存在則為-1 int [] smapping = new int[last]; for (int i = 0; i < last; ++i) { String section = s.substring(i, i + M); Integer mapped = mapping.get(section); if (mapped == null) { smapping[i] = -1; } else { smapping[i] = mapped; } } //fix the number of linear scans for (int i = 0; i < M; ++i) { //reset scan variables int currentFailures = failures; //number of current mismatches int left = i, right = i; Arrays.fill(table[1], 0); //here, simple solve the minimum-window-substring problem //保證右節(jié)點不超出邊界 while (right < last) { //保證左右節(jié)點之間的子字符串能夠包含所有的word值 while (currentFailures > 0 && right < last) { int target = smapping[right]; if (target != -1 && ++table[1][target] == table[0][target]) { --currentFailures; } right += M; } while (currentFailures == 0 && left < right) { int target = smapping[left]; if (target != -1 && --table[1][target] == table[0][target] - 1) { int length = right - left; //instead of checking every window, we know exactly the length we want if ((length / M) == words.length) { indexes.add(left); } ++currentFailures; } left += M; } } } return indexes; }
想要了解更多開發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號!將會不定期的發(fā)放福利哦~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67108.html
摘要:每次搜索中,我們通過哈希表維護一個窗口,比如中,我們先拿出。如果都不在數(shù)組中,那說明根本不能拼進去,則哈希表全部清零,從下一個詞開始重新匹配。 Substring with Concatenation of All Words You are given a string, s, and a list of words, words, that are all of the same...
摘要:使用而不是因為我們需要的是最值,中間值我們不在乎,所以一次收斂到最小。下面來三個需要查重并且記錄上次出現(xiàn)的位置,選擇以為例,走到用做檢查,發(fā)現(xiàn)出現(xiàn)過,把移到的下一個。是上個題目的簡易版,或者特殊版。 這里聊一聊解一類問題,就是滿足某一條件的substring最值問題。最開始我們以Minimum Window Substring為例,并整理總結(jié)leetcode里所有類似題目的通解。 Gi...
Problem Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome. Example 1: Inpu...
Problem Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one po...
摘要:解題思路,就是只順序不同但個數(shù)相同的字符串,那我們就可以利用的思想來比較每個字符串中字符出現(xiàn)的個數(shù)是否相等。 Find All Anagrams in a StringGiven a string s and a non-empty string p, find all the start indices of ps anagrams in s. Strings consists of...
閱讀 2720·2021-10-12 10:12
閱讀 2345·2021-09-02 15:41
閱讀 2577·2019-08-30 15:55
閱讀 1409·2019-08-30 13:05
閱讀 2446·2019-08-29 11:21
閱讀 3542·2019-08-28 17:53
閱讀 3037·2019-08-26 13:39
閱讀 808·2019-08-26 11:50