LeetCode(困难)串联所有单词的子串(c#)

题目为 给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

在这里插入图片描述
第一个思路为用一个全为0的字符串去存储每一个元素是否出现过,出现就变为1。进行判断。属于暴力算法,代码逻辑没有问题,但是超时了。代码如下

		public IList<int> FindSubstring(string s, string[] words)
        {
            int allCount = words.Count();
            List<int> res = new List<int>();
            if (allCount == 0)
            {
                return res;
            }
            bool[] flagAll = new bool[allCount];
            int countMax = words[0].Length;
            int resFlag = 0;
            int resTemp = 0;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < allCount; i++)
            {
                sb.Append("0");
            }
            string[] rs = new string[allCount];
            string equalsNums = sb.ToString();
            for (int i = 0; i <= s.Length - countMax * allCount; i++)
            {
                words.CopyTo(rs, 0);
                int wStart = i;
                resTemp = i;
                while (rs.ToList().Contains(s.Substring(wStart, countMax)))
                {
                    if (equalsNums[rs.ToList().IndexOf(s.Substring(wStart, countMax))] == '0')
                    {
                        var r = rs.ToList().IndexOf(s.Substring(wStart, countMax));
                        equalsNums = equalsNums.Remove(r, 1);
                        equalsNums = equalsNums.Insert(r, "1");
                        wStart += countMax;
                        resFlag++;
                        rs[r] = "";
                        if (resFlag == allCount)
                        {
                            res.Add(resTemp);
                            break;
                        }
                        if (wStart + countMax > s.Length)
                        {
                            break;
                        }
                    }
                    else
                    {
                        i += wStart;
                        break;
                    }
                }
                equalsNums = sb.ToString();
                resFlag = 0;
                continue;
            }
            return res;
        }

第二种思路是参考精选题解的方法,一个键值对,键存储元素,值存储元素出现次数。遍历时再创建一个键值对,将两个键值对比较。如果出现次数大于基准字符串出现次数,直接跳出。代码如下

		public IList<int> FindSubstring(string s, string[] words)
        {
            List<int> res = new List<int>();
            int wordNum = words.Length;
            if (wordNum == 0)
            {
                return res;
            }
            int wordLen = words[0].Length;
            Dictionary<string, int> dic = new Dictionary<string, int>();
            foreach (var item in words)
            {
                if (!dic.ContainsKey(item))
                {
                    dic.Add(item, 1);
                }
                else
                {
                    dic[item] += 1;
                }
            }
            for (int i = 0; i < s.Length - wordNum * wordLen+1; i++)
            {
                Dictionary<string, int> dicDetail = new Dictionary<string, int>();
                int num = 0;
                while (num< wordNum)
                {
                    string word = s.Substring(i+num* wordLen,wordLen);
                    if (dic.ContainsKey(word))
                    {
                        if (dicDetail.ContainsKey(word))
                        {
                            dicDetail[word] += 1;
                        }
                        else
                        {
                            dicDetail.Add(word, 1);
                        }
                        if (dicDetail[word] > dic[word])
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                    num++;
                }
                if (num==wordNum)
                {
                    res.Add(i);
                }
            }
            return res;
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章