gpt4 book ai didi

algorithm - 最长回文子串自上而下的递归方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:46:13 24 4
gpt4 key购买 nike

我正在尝试解决 Longest palindromic substring在力扣上。我知道这个问题的解决方案,例如围绕中心展开或 dynamic programming bottom up approach .出于纯粹的教育目的,我想以自上而下的递归方式解决这个问题。我正在尝试找到类似于描述的解决方案 herehere . (问题略有不同)。我有这个功能:

private (int Start, int End) Longest(string s, int i, int j)

它采用字符串 + 搜索的开始和结束位置。返回的元组是最长回文的开始和结束。我试图分成这些情况:

  1. 如果 s[i] == s[j] 调查 Longest(s, i+1, j-1)
  2. 调查最长的(s, i+1, j)
  3. 调查最长的(s, i, j - 1)
  4. 从这三个中返回最长的(返回的开始和结束之间的最大差异)

当然,我正在使用以元组 (int, int) 作为键(i 和 j 的值)的 Dictionary 来记住所有计算结果而不是再次计算它们。

完整代码在下面,但是当我尝试修复算法时,经过几次迭代后它变得非常困惑。我相信concreate代码不是很重要。

代码似乎返回了正确的结果,但在 Leetcode 上的 Time Limit Exceeded 失败。是否有正确的快速递归解决方案?我相信应该有 DP 自下而上的解决方案存在。

代码:

private readonly IDictionary<(int, int), (int, int)> _mem = new Dictionary<(int, int), (int, int)>();

private (int Start, int End) Longest(string s, int i, int j) {
if (i >= j) {
return (i, j);
}

if (_mem.TryGetValue((i, j), out var ret)) {
return ret;
}

var newI = i + 1;
var newJ = j - 1;

ValueTuple<int, int> removingTwo;

if (s[i] == s[j])
{
removingTwo = Longest(s, newI, newJ);

if (removingTwo.Item1 == newI && removingTwo.Item2 == newJ) {
removingTwo.Item1--;
removingTwo.Item2++;
}
}
else {
removingTwo = (1, 0);
}

var removingFirst = Longest(s, newI, j);
var removingLast = Longest(s, i, newJ);

var mT = removingTwo.Item2 - removingTwo.Item1;
var mF = removingFirst.End - removingFirst.Start;
var mL = removingLast.End - removingLast.Start;

var max = Math.Max(mT, mF);
max = Math.Max(max, mL);

ValueTuple<int, int> retVal;

if (max == mT) retVal = removingTwo;
else if (max == mF) retVal = removingFirst;
else retVal = removingLast;

_mem.Add((i, j), retVal);

return retVal;

}

编辑:工作自下而上的解决方案(从 geegsforgeegs 复制):

public string LongestPalindrome(string s) {
if (s.Length == 0) return "";
var table = new bool[s.Length, s.Length];
var len = s.Length;
for (int i = 0; i < len; i++) {
table[i,i] = true;
}

var start = 0;
var max = 1;
for (int i = 0; i < len - 1; i++) {
if (s[i] == s[i + 1]) {
start = i;
max = 2;
table[i, i+1] = true;
}
}

for (int k = 3; k <= len; ++k) {

// Fix the starting index
for (int i = 0; i < len - k + 1; ++i)
{
// Get the ending index of substring from
// starting index i and length k
int j = i + k - 1;

// checking for sub-string from ith index to
// jth index iff str.charAt(i+1) to
// str.charAt(j-1) is a palindrome
if (table[i + 1, j - 1] && s[i] == s[j]) {
table[i,j] = true;

if (k > max) {
start = i;
max = k;
}
}
}
}

return s.Substring(start, max);
}

最佳答案

这是一个通过LeetCode测试的Python递归方法。可能他们正在寻找一个恒定的空间解决方案。

f(i, k) 返回 (l, j),长度为 l 的最大元组及其起始索引,jmax 在此实例中查看返回元组的第一个元素,即 l,即回文的长度。

def longestPalindrome(self, s):
def f(i, k):
return max(
# next iteration
f(i - 1, 1) if k < 2 and i > 0 else (-1,-1),
f(i - 1, 2) if k < 2 and i > 0 and s[i-1] == s[i] else (-1, -1),

# a larger palindrome than this one
f(i - 1, k + 2) if i > 0 and i + k < len(s) and s[i-1] == s[i + k] else (-1, -1),

# this one
(k, i)
)

(l, j) = f(len(s) - 1, 1)
return s[j:j+l]

关于algorithm - 最长回文子串自上而下的递归方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53696050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com