[Swift]LeetCode30. 与所有单词相关联的字串 | 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 = "wordgoodstudentgoodword",
  words = ["word","student"]
Output: []


给定一个字符串 s 和一些长度相同的单词 words。在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置。

注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

示例 1:

输入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
输出: [0,9]
解释: 从索引 0 和 9 开始的子串分别是 "barfoor" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。

示例 2:

输入:
  s = "wordgoodstudentgoodword",
  words = ["word","student"]
输出: []

304ms
 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         guard !words.isEmpty else {
 4             return []
 5         }
 6         guard !s.isEmpty else {
 7             return words.contains("") ? [0] : []
 8         }
 9
10         let string = Array(s)
11         let wordLength = words[0].count
12         let totalWordLength = words.count * wordLength
13
14         guard totalWordLength <= string.count else {
15             return []
16         }
17
18         let originalWordToCount = words.reduce(into: [:], { $0[$1, default:0] += 1 })
19
20         var startingIndices: [Int] = []
21
22         for i in 0..<wordLength {
23
24             var startIndex = i
25             var wordToCount = originalWordToCount
26
27             for j in stride(from: i, to: string.count-wordLength+1, by: wordLength) {
28
29                 let word = String(string[j..<(j+wordLength)])
30
31                 if let originalCount = originalWordToCount[word] {
32
33                     while wordToCount[word] == nil {
34                         let startWord = String(string[startIndex..<(startIndex+wordLength)])
35                         wordToCount[startWord, default: 0] += 1
36                         startIndex += wordLength
37                     }
38
39                     if let currentCount = wordToCount[word] {
40                         if currentCount == 1 {
41                             wordToCount[word] = nil
42                         } else {
43                             wordToCount[word] = currentCount - 1
44                         }
45                     }
46
47                     if wordToCount.isEmpty {
48                         startingIndices.append(startIndex)
49
50                          let startWord = String(string[startIndex..<(startIndex+wordLength)])
51                         wordToCount[startWord, default: 0] += 1
52                         startIndex += wordLength
53                     }
54
55                 } else {
56                     // reset
57                     startIndex = j+wordLength
58                     wordToCount = originalWordToCount
59                 }
60             }
61         }
62
63         return startingIndices
64     }
65 }


312ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         guard !words.isEmpty else {
 4             return []
 5         }
 6         guard !s.isEmpty else {
 7             return words.contains("") ? [0] : []
 8         }
 9
10         let string = Array(s)
11
12         let wordLength = words[0].count
13         let totalWordLength = words.count * wordLength
14
15         guard string.count >= totalWordLength else {
16             return []
17         }
18
19         let originalWordToCount = words.reduce(into: [:], { $0[$1, default: 0] += 1 })
20
21         var startingIndices: [Int] = []
22
23         for i in 0..<wordLength {
24
25             var startIndex = i
26             var wordToCount: [String:Int] = [:]
27             var wordCount = 0
28
29             for j in stride(from: i, to: string.count - wordLength + 1, by: wordLength) {
30
31                 let word = String(string[j..<(j+wordLength)])
32
33                 if let originalCount = originalWordToCount[word] {
34
35                     wordToCount[word, default: 0] += 1
36                     wordCount += 1
37
38                     while let count = wordToCount[word], count > originalCount {
39                         let startWord = String(string[startIndex..<(startIndex+wordLength)])
40                         wordCount -= 1
41                         wordToCount[startWord, default: 1] -= 1
42                         startIndex += wordLength
43                     }
44
45                     if wordCount == words.count {
46                         startingIndices.append(startIndex)
47
48                         let startWord = String(string[startIndex..<(startIndex+wordLength)])
49                         wordCount -= 1
50                         wordToCount[startWord, default: 1] -= 1
51                         startIndex += wordLength
52                     }
53
54                 } else {
55                     // reset
56                     startIndex = j+wordLength
57                     wordToCount = [:]
58                     wordCount = 0
59                 }
60             }
61         }
62
63         return startingIndices
64     }
65 }


424ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3
 4         guard !words.isEmpty else {
 5             return []
 6         }
 7         guard !s.isEmpty else {
 8             return words.contains(s) ? [0] : []
 9         }
10
11         let string = Array(s)
12         let wordLength = words[0].count
13         let totalWordLength = wordLength * words.count
14
15         guard totalWordLength <= string.count else {
16             return []
17         }
18
19         let originalWordToCount = words.reduce(into: [:], { $0[$1, default: 0] += 1 })
20
21         var startingIndices: [Int] = []
22
23         for i in 0..<wordLength {
24
25             var startIndex = i
26             var currentWordToCount = originalWordToCount
27
28             for j in stride(from: i, to: string.count-wordLength+1, by: wordLength) {
29
30                 let word = String(string[j..<(j+wordLength)])
31
32                 if let originalCount = originalWordToCount[word] {
33
34                     while currentWordToCount[word] == nil {
35                         let startWord = String(string[startIndex..<(startIndex+wordLength)])
36                         startIndex += wordLength
37                         currentWordToCount[startWord, default: 0] += 1
38                     }
39
40                     if let currentCount = currentWordToCount[word] {
41                         if currentCount == 1 {
42                             currentWordToCount[word] = nil
43                         } else {
44                             currentWordToCount[word] = currentCount-1
45                         }
46                     }
47
48                     if currentWordToCount.isEmpty {
49                         startingIndices.append(startIndex)
50
51                         // get a new combination
52                         let startWord = String(string[startIndex..<(startIndex+wordLength)])
53                         startIndex += wordLength
54                         currentWordToCount[startWord] = 1
55                     }
56
57                 } else {
58                     // reset
59                     startIndex = j+wordLength
60                     currentWordToCount = originalWordToCount
61                 }
62             }
63         }
64
65         return startingIndices
66     }
67 }


1128ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         if words.isEmpty {
 4             return []
 5         }
 6         let wordLen = words[0].count
 7         let substrLen = words.count * wordLen
 8
 9         if s.count <  substrLen {
10             return []
11         }
12
13         var answer = [Int]()
14         answer.reserveCapacity(s.count)
15
16         var dict = [String:Int]()
17         for w in words {
18             var count = 1
19             if let v = dict[w] {
20                 count = count + v
21             }
22             dict[w] = count
23         }
24
25         var i = s.startIndex
26         let end = s.index(s.endIndex, offsetBy: -substrLen)
27         while i <= end {
28             if isSubstring(s[i..<s.index(i, offsetBy:substrLen)], dict, wordLen) {
29                 answer.append(s.distance(from: s.startIndex, to: i))
30             }
31             i = s.index(after: i)
32         }
33         return answer
34     }
35
36     func isSubstring(_ s: Substring, _ words: [String:Int], _ wordLen: Int) -> Bool {
37         var d = words
38         var substr = s
39         while !substr.isEmpty {
40             let w = String(substr[substr.startIndex..<substr.index(substr.startIndex, offsetBy: wordLen)])
41             if let c = d[w], c > 0 {
42                 d[w] = c - 1
43             } else {
44                 return false
45             }
46             substr = substr[substr.index(substr.startIndex, offsetBy: wordLen)...]
47         }
48         return true
49     }
50 }


1852ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         if s == nil || words.count == 0 {
 4             return []
 5         }
 6         var result: [Int] = []
 7         var dict1: [String: Int] = [String: Int]()
 8         var dict2: [String: Int] = [String: Int]()
 9         let stringLength: Int = s.count
10         let wordsListSize: Int = words.count
11         let wordLength: Int = words[0].count
12         for i in 0 ..< wordsListSize {
13             if dict1[words[i]] == nil {
14                 dict1[words[i]] = 1
15             } else {
16                 dict1[words[i]]! += 1
17             }
18         }
19         var s1: String
20         var s2: String
21         var counter1: Int
22         var counter2: Int
23         for i in 0 ..< wordLength {
24             counter1 = 0
25             counter2 = i
26             var j = i;
27             while j < stringLength {
28                 s1 = s[j..<j+wordLength]
29                 if dict1[s1] == nil {
30                     dict2.removeAll(keepingCapacity: false)
31                     counter1 = 0
32                     counter2 = j + wordLength
33                 } else if dict2[s1] == nil || dict2[s1]! < dict1[s1]! {
34                     if dict2[s1] == nil {
35                         dict2[s1] = 1
36                     } else {
37                         dict2[s1]! += 1
38                     }
39                     counter1 += 1
40                 } else {
41                     s2 = s[counter2..<counter2+wordLength]
42                     while s2 != s1 {
43                         dict2[s2]! -= 1
44                         counter1 -= 1
45                         counter2 += wordLength
46                         s2 = s[counter2..<counter2+wordLength]
47                     }
48                     counter2 += wordLength
49                 }
50                 if counter1 == wordsListSize {
51                     result.append(counter2)
52                     s2 = s[counter2..<counter2+wordLength]
53                     dict2[s2]! -= 1
54                     counter1 -= 1
55                     counter2 += wordLength
56                 }
57                 j += wordLength
58             }
59             dict2.removeAll(keepingCapacity: false)
60         }
61         return result
62     }
63 }
64
65 private extension String {
66     subscript (range: Range<Int>) -> String {
67         guard let localEndIndex = self.index(self.startIndex, offsetBy: range.upperBound, limitedBy: self.endIndex) else {
68             return String(self[self.index(self.startIndex, offsetBy: range.lowerBound)..<self.endIndex])
69         }
70         return String(self[self.index(self.startIndex, offsetBy: range.lowerBound)..<localEndIndex])
71     }
72 }


3192ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         if words.count == 0 { return [] }
 4         let len = words[0].count
 5
 6         let s = Array(s.characters)
 7         let concatLen = len * words.count
 8
 9         if s.count < concatLen { return [] }
10
11         // Map word to count
12         var dict = [String: Int]()
13         for i in 0..<words.count {
14             let count = (dict[words[i]] ?? 0) + 1
15             dict[words[i]] = count
16         }
17
18         var res = [Int]()
19         for i in 0..<(s.count-words.count*len+1) {
20             var track = [String: Int]()
21             var ok = true
22             let startSequence = (0..<words.count).map { i + $0 * len }
23             for start in startSequence {
24                 let substring = String(s[start..<start+len])
25                 let count = (track[substring] ?? 0) + 1
26                 if count > (dict[substring] ?? 0) {
27                     ok = false
28                     break
29                 }
30                 track[substring] = count
31             }
32
33             if ok {
34                 res.append(i)
35             }
36         }
37
38         return res
39     }
40 }


3480ms

 1 class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         guard s.count > 0 && words.count > 0 else {
 4         return []
 5     }
 6
 7     var counts = [String: Int]()
 8     words.forEach { word in
 9         counts[word, default: 0] += 1
10     }
11
12     var indices = [Int]()
13     let ss = s.utf8CString
14     let n = s.count
15     let wc = words.count
16     let len = words.first!.count
17     for i in 0..<(n - wc * len + 1) {
18         var seen = [String: Int]()
19         var j = 0
20         while j < wc {
21             let cs = Array(ss[(i + j * len)..<(i + (j + 1) * len)]) + [0]
22             let word = String(cString: cs)
23             if words.contains(word) {
24                 seen[word, default: 0] += 1
25                 if seen[word]! > counts[word]! {
26                     break
27                 }
28             } else {
29                 break
30             }
31             j += 1
32         }
33
34         if j == wc {
35             indices.append(i)
36         }
37     }
38     return indices
39     }
40 }


3556ms

 1  class Solution {
 2     func findSubstring(_ s: String, _ words: [String]) -> [Int] {
 3         var results:[Int] = []
 4         if s == nil || s.isEmpty || words == nil || words.isEmpty {return results}
 5         var h:[String: Int] = [String: Int]()
 6         for word in words
 7         {
 8             if h[word] == nil
 9             {
10                 h[word] = 1
11             }
12             else
13             {
14                 h[word] = h[word]! + 1
15             }
16         }
17         var len:Int = words[0].count
18         for offset in 0..<len
19         {
20             var f:[String: Int] = [String: Int]()
21             var from:Int = offset
22             var count:Int = 0
23             for i in stride(from: offset,through:s.count - len,by: len)
24             {
25                 var word:String = s.subString(i,len)
26                 var hc:Int? = h[word]
27                 if hc == nil
28                 {
29                     from = i + len
30                     count = 0
31                     f = [String: Int]()
32                     continue
33                 }
34                 var fc:Int? = f[word]
35                 if fc == nil
36                 {
37                     fc = 1
38                 }
39                 else
40                 {
41                     fc = fc! + 1
42                 }
43                 f[word] = fc
44                 count += 1
45                 while (fc! > hc!)
46                 {
47                     var fword = s.subString(from,len)
48                     f[fword] = f[fword]! - 1
49                     fc = f[word]!
50                     from += len
51                     count -= 1
52                 }
53                 if count == words.count
54                 {
55                    results.append(from)
56                 }
57             }
58         }
59         return results
60     }
61 }
62
63 extension String {
64     // 截取字符串:指定区间
65     // - Parameter range: 闭区间
66     // - Returns: 子字符串
67     func subString(_ begin:Int,_ count:Int) -> String {
68         let start = self.index(self.startIndex, offsetBy: begin)
69         let end = self.index(self.startIndex, offsetBy: begin + count - 1)
70         return String(self[start...end])
71     }
72 }

原文地址:https://www.cnblogs.com/strengthen/p/9897592.html

时间: 2024-11-09 06:10:57

[Swift]LeetCode30. 与所有单词相关联的字串 | Substring with Concatenation of All Words的相关文章

[leetcode] 30. 与所有单词相关联的字串(cn第653位做出此题的人~)

30. 与所有单词相关联的字串 这个题做了大概两个小时左右把...严重怀疑leetcode的judge机器有问题.同样的代码交出来不同的运行时长,能不能A题还得看运气? 大致思路是,给words生成一关于s的字典,用来记录每个word在s中出现的所有位置,注意可能会出现相同的word.然后递归枚举words的排列情况,一一校验是否符合条件(即连在一起).用到了递归+记忆化搜索+kmp+几个剪枝 一直最后几个测试用例上TLE,囧啊,甚至一度怀疑是不是还有更优的做法. 然后开始考虑剪枝: 记忆化搜索

Leetcode——30.与所有单词相关联的字串【##】

@author: ZZQ @software: PyCharm @file: leetcode30_findSubstring.py @time: 2018/11/20 19:14 题目要求: 给定一个字符串 s 和一些长度相同的单词 words.在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置. 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序. 示例 1: 输入: s = "barfoothefoobarman&qu

30. 与所有单词相关联的字串、java实现

题目描述: 给定一个字符串 s 和一些长度相同的单词 words.在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置. 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序. 示例 1: 输入: s = "barfoothefoobarman", words = ["foo","bar"] 输出: [0,9] 解释: 从索引 0 和 9 开始的子串分别是 "barfo

创建Hive/hbase相关联的表异常

hive> CREATE TABLE hperson(id string, name string,email string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":id,cf1:name,cf2:email") TBLPROPERTIES ("hbase.table.

表单标签&lt;label&gt;----------------------用for属性 和radio 的id相关联 可以让鼠标点字就相当于点击radio

定义和用法 <label> 标签为 input 元素定义标注(标记). label 元素不会向用户呈现任何特殊效果.不过,它为鼠标用户改进了可用性.如果您在 label 元素内点击文本,就会触发此控件.就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上. <label> 标签的 for 属性应当与相关元素的 id 属性相同. <form><label for="male">Male</label><

Entity Framework 6 Recipes 2nd Edition(12-5)译 -&gt; 自动删除相关联实体

12-5. 自动删除相关联实体 问题 当一个实体被删除时,你想自动删除它相关联的实体 解决方案 假设你有一个表结构由一个course (科目), course 的classes (课程),以及enrollment (登记学生选课),如 Figure 12-5所示:. Figure 12-5. The Course, Class, and Enrollment tables in our database 由上述表生成一个模型,如下图Figure 12-6所示:. Figure 12-6. A m

已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭。

多次用到SqlDataReader 要先关闭,再执行ExecuteNonQuery操作 每用一次需要先进行关闭,再执行新的一次,要不然就会报错“已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭.” 那么如何解决呢? 方法有两种1,在ConnectionString加上MultipleActiveResultSets=true,但只适用于SQL 2005以后的版本2.选择读出SqlDataReader 中的数据给List或者arraylist之类的,之后进行关闭返回

Asp.Net WebApi 集成OWIN架构后,出现 “没有 OWIN 身份验证管理器与此请求相关联” 的解决办法

在Asp.Net WebApi 项目中开启OWIN模块之后,如果没有在OWIN的Startup类中配置认证方式,调用WebApi的相关Controller和Action就会出现如下异常: 出现错误. 没有 OWIN 身份验证管理器与此请求相关联. ExceptionType:System.InvalidOperationException StackTrace: 在 System.Web.Http.Owin.PassiveAuthenticationMessageHandler.Suppress

code first提示已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭解决方法

使用codefirst查询当然是必不可少的,但有时不小心可能很简单的查询也会导致异常. 下面用codefirst做个示例简单演示下异常发生的场景: var attendlist = db.Database.SqlQuery<AttendCountViewModel>("select STUDENTID,SUM(isnull(REALHOUR,0)) As REALHOUR from ATTEND_LIST where ATTENDDATE='" + geDate + &qu