Skip to content

finished 30 #135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions Hard/SubstringwithConcatenationofAllWords.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import java.util.*;

/**
* 30. Substring with Concatenation of All Words
* 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].
* Tags: Hash Table Two Pointers String
* Similar Problems: (H) Minimum Window Substring
* @author chenshuna
*/

public class SubstringwithConcatenationofAllWords {
public static List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new ArrayList<Integer>();
if( s==null || words == null || s.length() == 0 || words.length == 0 ) return res;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

HashMap<String, Integer> wordDict = new HashMap<String, Integer>();
int wordLen = words[0].length();
for(String word : words){
if(wordDict.containsKey(word))
wordDict.put(word, wordDict.get(word) + 1);
else
wordDict.put(word, 1);
}
/**
* outside loop
* bar/foo/the/foo/bar/man
* b/arf/oot/hef/oob/arm/an
* ba/rfo/oth/efo/oba/rma/n
*/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should't use javadoc comment within a function. Use multi-line comment instead. And these comments are very vague. Please remove them.

for(int i = 0; i < wordLen; i++){
HashMap<String, Integer> sMap = new HashMap<String, Integer>();
Copy link
Owner

@FreeTymeKiyan FreeTymeKiyan Apr 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating another map and use count to compare, you can just create a copy of the wordDict, then reduce count or remove key from the map while you try to find the concatenation. When the copy is empty, you find one result.

int count = 0;
int start = i;
for(int j = i; j <= s.length() - wordLen; j = j + wordLen){
String temp = s.substring(j, j + wordLen);
if(wordDict.containsKey(temp)){
if(sMap.containsKey(temp))
sMap.put(temp, sMap.get(temp) + 1);
else
sMap.put(temp, 1);

if(sMap.get(temp) <= wordDict.get(temp))
count++;
else
{
while(sMap.get(temp) > wordDict.get(temp))
{
String temp2 = s.substring(start, start + wordLen);
sMap.put(temp2, sMap.get(temp2) - 1);
if(sMap.get(temp2) < wordDict.get(temp2)) count--;
start = start + wordLen;
}
}

if(count == words.length){
res.add(start);
String word = s.substring(start, start + wordLen);
sMap.put(word, sMap.get(word) - 1);
count--;
start = start + wordLen;
}
}
else
{
sMap.clear();
count = 0;
start = j + wordLen;
}
}
}
return res;
}

public static void main(String[] args) {
String s = "barfoothefoobarman";
String[] words = {"foo", "bar"};
System.out.println(findSubstring(s, words));
}
}