Заметки LeetCode [44]
Проблема
Подход 1: ДФС
Найдите все возможные подпоследовательности, используя DFS, а затем найдите непересекающиеся подпоследовательности с максимальным произведением длины.
Выполнение
class Solution { private var candidates = mutableListOf<List<Int>>() fun maxProduct(s: String): Int { candidates = mutableListOf() search(s, listOf(), 0) return calculate() } private fun calculate(): Int { var max = Int.MIN_VALUE for (i in candidates.indices) { val p1 = candidates[i] for (j in i + 1 until candidates.size) { val p2 = candidates[j] if (!p1.any { it in p2 }) { val mul = p1.size * p2.size if (mul > max) { max = mul } } } } return max } private fun search(s: String, list: List<Int>, curIndex: Int) { if (curIndex < s.length) { val newList = list.toMutableList() search( s, newList.apply { add(curIndex) }, curIndex + 1 ) search(s, list, curIndex + 1) } else { var result = "" list.forEach { result += s[it] } if (isPalindromic(result)) { candidates.add(list) } } } private fun isPalindromic(s: String): Boolean { if (s.isEmpty()) return false for (i in 0..s.length / 2) { if (s[i] != s[s.length - 1 - i]) return false } return true } }
Анализ сложности
- Временная сложность: O(sigma_0_n(2^n))
- Сложность пространства: O(n* 2^n)
Подход 2: улучшенная DFS
Так как для каждого символа c
в заданной строке s
, c
будет либо
- In
subsequence1
- In
subsequence2
- Ни в
subsequence1
, ни вsubsequence2
Повторение будет:
- If
i < s.length
,
F(i, s1, s2) = max( F(i+1, s1 + c, s2), F(i+1, s1, s2 + c), F(i+1, s1, s2) )
- Если
i == s.length
и обаs1
иs2
являются палиндромами, вернуть произведение их длины.
Выполнение
class Solution { private var max = Int.MIN_VALUE private fun isPalindromic(s: String): Boolean { if (s.isEmpty()) return false for (i in 0..s.length / 2) { if (s[i] != s[s.length - 1 - i]) return false } return true } fun maxProduct(s: String): Int { max = Int.MIN_VALUE search(s, 0, "", "") return max } private fun search(s: String, index: Int, s1: String, s2: String) { if (index < s.length) { search(s, index + 1, s1 + s[index], s2) search(s, index + 1, s1, s2 + s[index]) search(s, index + 1, s1, s2) } else { if (isPalindromic(s1) && isPalindromic(s2)) { val mul = s1.length * s2.length if (mul > max) { max = mul } } } } }
Анализ сложности
- Временная сложность: O(sigma_0_n(3^n))
- Сложность пространства: O(n)