【问题标题】:Having a tough time understanding longestPalindrome algorithm很难理解最长回文算法
【发布时间】:2020-04-02 01:56:21
【问题描述】:

我发现这个解决方案对于在子字符串中查找最长回文的算法问题很有意义。但是,我很难理解扩展功能实际上在做什么。我以为它会从中心运行,但控制台日志显示它是为整个字符串运行的。我很难理解为什么它会进入与 s[begin] === s[end] 不同的任何字符的 while 循环,这就是我认为这条线正在阻止的。我不确定为什么 expand 也被调用了两次。另外,为什么我们在返回子字符串时要添加begin + 1 而不仅仅是begin。代码如下。任何有关扩展如何工作的说明都将不胜感激。

var longestPalindrome = function (s) {
    //either when empty string or is a single character
    if (!s || s.length <= 1) return s

    let longest = s.substring(0, 1)

    for (let i = 0; i < s.length; i++) {
        let temp = expand(s, i, i, 'first')
        // console.log(temp, 'i am the first')
        if (temp.length > longest.length) {
            longest = temp
        }
        temp = expand(s, i, i + 1, 'second')
        // console.log(temp, 'i am the second')
        if (temp.length > longest.length) {
            longest = temp
        }
    }
    return longest
}

const expand = (s, begin, end, counter) => {
    while (begin >= 0 && end <= s.length - 1 && s[begin] === s[end]) {
        console.log(s, 'i am string')
        console.log(begin, 'i am begin')
        console.log(end, 'i am begin')
        console.log(s[begin], s[end])
        console.log(counter)
        begin--
        end++
    }
    return s.substring(begin + 1, end)
}

console.log(longestPalindrome('cbbd'))
console.log(longestPalindrome('babad'))
console.log(longestPalindrome('ac'))
console.log(longestPalindrome('abb'))

【问题讨论】:

    标签: javascript algorithm palindrome


    【解决方案1】:

    好吧,假设我们想在 s = 'abba' 时找到 s 的回文。

    注意:将扩展想象成一个回文查找器,它接收中心索引。请记住,我将在之后解释扩展是如何工作的

    我们将扩展的中心从 0 移到 3(最终索引)。首先,它检查从 begin = 0 到 end = 0 的展开。

    s = 'abba'
    

    如果 begin = 0 和 end = 0,展开返回 'a'。

    v___
    abba //only the palindrome from 0 is 'a'
    

    如果 begin = 0 且 end = 1,展开返回 ' '。

    _v___
    a bba //there are no palindrome from between 0 and 1 
    

    如果 begin = 1 和 end = 1,展开返回 'b'。

    _v__
    abba //only the palindrome from 1 is 'b'
    

    如果 begin = 1 且 end = 2,则展开返回 'abba'。

    __v__
    ab ba //the palindrome from between b and b is 'abba'
    

    如果 begin = 2 和 end = 2,展开返回 'b'。

    如果 begin = 2 且 end = 3,展开返回 ' '。

    如果 begin = 3 和 end = 3,展开返回 'a'。

    此时,我们已经测试了 s 的所有可能回文。最后,代码返回迄今为止最长的回文,在本例中为 'abba'。

    注意为什么我们需要执行两次扩展。在 i = 1 时,我们可以从中心寻找回文。

    _v__
    abba
    

    但也从b和b之间的地方

    __v__
    ab ba
    

    前者返回'b',后者返回'abba'。这就是为什么您需要为每个 i 执行 2 次扩展。


    现在,expand 函数内部到底发生了什么? 让我们使用这个例子。 s = 'aacdeedcba',begin = 4 和 end = 5。

    首先,while 循环检查 s[begin] == s[end]。

    ____vv____
    aacdeedcba
    

    显然 'e' === 'e' 是正确的,所以我们将把 begin 移到左边,end 移到右边。

    我们将再次检查 s[begin] === s[end]。

    ___v__v____
    aacdeedcba
    

    再一次,'d' === 'd' 是真的,所以我们将把 begin 移到左边,end 移到右边。

    我们会再次检查。

    __v____v__
    aacdeedcba
    

    再一次,'c' === 'c' 是真的,所以我们将把 begin 移到左边,end 移到右边。

    我们会再次检查。

    _v______v_
    aacdeedcba
    

    这一次,'a' === 'b' 不是真的。所以while循环停止了。并且扩展函数返回'cdeedc'。

    【讨论】:

      【解决方案2】:

      但是,我很难理解扩展功能实际上在做什么。我以为它会从中心运行,但控制台日志显示它是针对整个字符串运行的

      回文可以有两种类型
      1. 偶数长度回文,例如- “阿巴”
      2. 奇数回文,例如- “阿巴”

      现在,给定字符串的每个索引都可以是这些回文类型中的任何一种的中心。 因此,字符串的每个索引都被测试了这种可能性。

      longestPalindrome 函数获取字符串,并为字符串的每个索引测试该索引作为奇数长度回文和偶数长度回文的中心。

      expand 函数获取两个中心索引并开始向外扩展它们。对于奇数长度的回文,应该将中心字符与其自身进行比较。因此,expandbeginend 作为相同的索引来调用。

      我很难理解为什么它会进入与 s[begin] === s[end] 不同的任何字符的 while 循环,这就是我认为这条线正在阻止的。

      longestPalindrome 将发送两个索引,这样条件s[begin] === s[end] 不成立,但while 循环将检查而不进一步扩展它们。如果您愿意,可以通过 longestPalindrome 函数阻止此功能。

      我也不知道为什么 expand 被调用了两次。

      这是因为这两种回文的长度是基于它们的长度。您需要测试这两种类型。

      另外,为什么我们在返回子字符串时添加 begin + 1 而不是 begin。

      这是因为当 if 退出 while 循环时,begin 是一回事。您可以在纸上进行模拟以更好地理解。

      【讨论】:

        猜你喜欢
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        • 2020-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多