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.
Example 1:
Input:
s = “barfoothefoobarman”,
words = [“foo”,“bar”]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are “barfoor” and “foobar” respectively.
The output order does not matter, returning [9,0] is fine too.
Example 2:
Input:
s = “wordgoodgoodgoodbestword”,
words = [“word”,“good”,“best”,“word”]
Output: []
输入为一个字符串 s 和一个字符串数组 words,words 中的字符串长度是一样长的。在字符串 s 中找到子字符串的起始位置,子字符串包含 words 中的所有字符串。
static public IList<int> FindSubstring(string s, string[] words)
{
List<int> result = new List<int>();
if (words.Length == 0 || words[0].Length == 0 || s.Length < words.Length * words[0].Length)
{
return result;
}
int step = words[0].Length;
Dictionary<string, int> dic_words = new Dictionary<string, int>();
foreach (string str in words)
{
if (dic_words.ContainsKey(str))
{
dic_words[str]++;
}
else
{
dic_words.Add(str,1);
}
}
for (int i = 0; i <= s.Length- step * words.Length; i++)
{
if (words.Contains(s.Substring(i,step)))
{
string[] sub_array = new string[words.Length];
Dictionary<string, int> dic_search = new Dictionary<string, int>();
int match_time = 0;
for (int j = 0; j < words.Length; j++)
{
string key = s.Substring(i + j * step, step);
if (dic_words.ContainsKey(key))
{
if (!dic_search.ContainsKey(key))
{
dic_search.Add(key, 1);
}
else
{
dic_search[key]++;
}
if (dic_search[key] <= dic_words[key])
{
match_time++;
}
else
{
break;
}
}
else
{
break;
}
}
if (match_time == words.Length)
{
result.Add(i);
}
}
}
return result;
}
附上几个测试用例:
“aaaaaaaa”
[“aa”,“aa”,“aa”]
0,1,2
“wordgoodgoodgoodbestword”
[“word”,“good”,“best”,“word”]
0
“wordgoodgoodgoodbestword”
[“word”,“good”,“best”,“good”]
8
虽然代码是写出来了,但在解题的过程中很多次提交都因为超过时间显示被驳回。
一个失败思路是,先把数组通过排列组合把所有能组成的字符串都生成出来,后来发现当数组过大的时候(18左右),可能的结果就是 18 的阶乘,计算的时间就很长了,不可取。
下面记录解题过程遇到的知识点。
正则表达式查找字符串中所有结果的位置
MSDN上找到的例子
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+es\b";
string sentence = "NOTES: Any notes or comments are optional.";
// Call Matches method without specifying any options.
foreach (Match match in Regex.Matches(sentence, pattern))
Console.WriteLine("Found '{0}' at position {1}",
match.Value, match.Index);
Console.WriteLine();
// Call Matches method for case-insensitive matching.
foreach (Match match in Regex.Matches(sentence, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("Found '{0}' at position {1}",
match.Value, match.Index);
}
}
// The example displays the following output:
// Found 'notes' at position 11
//
// Found 'NOTES' at position 0
// Found 'notes' at position 11
c# 判断两个数组值是否相等
参考网站:
https://stackoverflow.com/questions/4423318/how-to-compare-arrays-in-c
解题时候简单的string数组排列组合(递归)
static public IList<string> StringAC(string[] words)
{
List<string> result = new List<string>();
if (words.Length == 1)
{
result.Add(words[0]);
return result;
}
else
{
for (int i = 0; i < words.Length; i++)
{
List<string> temp_list = new List<string>();
for (int j = 0; j < words.Length; j++)
{
if (i == j) continue;
temp_list.Add(words[j]);
}
if (temp_list.Count > 0)
{
foreach (var str in StringAC(temp_list.ToArray()))
{
result.Add(words[i] + str);
}
}
}
}
return result;
}