【问题标题】:Make first string the Anagram of the second string?使第一个字符串成为第二个字符串的 Anagram?
【发布时间】:2016-03-29 14:05:20
【问题描述】:

每个测试用例将包含一个长度为 len(S1)+len(S2) 的字符串,这将是两个字符串的串联。给定的字符串将仅包含从 a 到 z 的字符。

任务

找出第一个字符串最少字符数(这将是给定字符串的前半部分)更改为使其成为第二个字符串的变位词。(这将是给定字符串的后半部分)。

输入:

aaabbb

输出:3

因为需要将 3 a(s) 替换为 3 b(s) 才能使 string1(aaa) 成为 string2(bbb) 的字谜

我的方法:

如果字符串长度不是偶数..那么前半部分不能是后半部分的字谜...那么print -1

否则:

  1. 我计算每个字母表的字符数并将其存储为一个包含 26 个元素的数组。表示从 a-z 开始的每个字母表的重复次数。

  2. 我为 2 个字符串创建了 2 个这样的数组。

3.我检查两个数组以打印需要更改的字符数。由于我需要将第一个字符串作为第二个字符串的字谜。我将检查两个数组。

Firststring[i] > SecondString[i] ...递增计数!

这种方法需要 o(n^2) 时间。 (遍历每个字符串并为每个字符串形成数组)。

我需要一个更好的解决方案!

【问题讨论】:

  • 提示:如果对单词的字母进行排序会发生什么?
  • 使用地图而不是数组来存储每个字母的重复?
  • @JonSkeet ... 排序一个单词然后?
  • 不,只是使用一个字符串...例如将“apple”映射到“aelpp”。考虑一下对互为字谜的单词这样做的结果。当然,这只有助于“检查两个单词是否是字谜”——而不是更大的任务。我不太关注更大的任务,部分原因是你没有给出任何例子。
  • 嗯好吧!但是排序并没有给出优化的解决方案?

标签: optimization anagram


【解决方案1】:

在线性时间 (O(n)) 中运行的非常简单的方法如下:

  • 让我们将两个子字符串称为strAstrB 以进行下面的讨论。对于每个子字符串:将字符串中的字符映射到一个数组,该数组保存字符串中特定字符的出现次数。例如,如果假设字符串中只有非大写字母,则将每个字符的 ASCII 值映射到大小为 26(英文字母)的整数数组的条目,将 ASCII 值移动 -96 以获得映射 ASCII (a...z) -> 索引(0...25)。在接下来的讨论中,我们将这些“出现次数”数组称为ab,分别对应于子字符串strAstrB
  • 此后,对于每个索引i(在 0...25 中),其中a[i] * b[i] > 0,值min(a[i], b[i]) 向我们显示了ab 中与索引关联的字符的符合顺序i.
  • 合规顺序的总和给出了子字符串strAstrB 之间的总合规,如果这个总和等于这些子字符串的长度(它们的长度相等,或者返回是-1 ),那么这两个子串 strAstrB 是彼此的字谜。

下面的例子展示了这个在 Swift 中的实现,但是我使用了一种纯粹的命令式方法,所以它应该很容易被翻译成你选择的最喜欢的编程语言。

let myString = "aaabbb"
var myOutput: Int?
let numChars = myString.characters.count

if numChars%2 == 0 {

    let midIndex = myString.startIndex.advancedBy(numChars/2)
    let myLeftString = myString.substringToIndex(midIndex)
    let myRightString = myString.substringFromIndex(midIndex)

    let numDifferentLetters = 26 // asymptotic behaviour: assume n > numDifferentLetters
    var letterOccurencesLhs = [Int](count: numDifferentLetters, repeatedValue: 0) // < n
    var letterOccurencesRhs = letterOccurencesLhs // swift: arr value type, < n

    // n/2
    for charAscii in myLeftString.utf8 {
        letterOccurencesLhs[Int(charAscii)-96] += 1
    }

    // n/2
    for charAscii in myRightString.utf8 {
        letterOccurencesRhs[Int(charAscii)-96] += 1
    }

    // check order of compliance for each letter, w.r.t. numDiffLetters, < n
    var mySum = 0
    for i in 0 ..< numDifferentLetters {
        if letterOccurencesLhs[i] * letterOccurencesRhs[i] > 0 {
            mySum += min(letterOccurencesLhs[i], letterOccurencesRhs[i])
        }
    }

    myOutput = numChars/2-mySum

}
else {
    myOutput = -1
}

print("Output: \(myOutput!)") // 3 for "aaabbb"
                              // 2 for "aaabbbbbbbab"

    // Complexity: O(n)

【讨论】:

    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 2018-04-23
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多