diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README.md b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README.md index b2ee078a658b1..a58e15eb464b1 100644 --- a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README.md +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README.md @@ -96,25 +96,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3503.Lo #### Python3 ```python - +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans ``` #### Java ```java - +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; ``` #### Go ```go +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} +``` +#### TypeScript + +```ts +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +} ``` diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README_EN.md b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README_EN.md index ad49088900286..82657f2452672 100644 --- a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README_EN.md +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/README_EN.md @@ -94,25 +94,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3503.Lo #### Python3 ```python - +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans ``` #### Java ```java - +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; ``` #### Go ```go +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} +``` +#### TypeScript + +```ts +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +} ``` diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.cpp b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.cpp new file mode 100644 index 0000000000000..730bfd925a29d --- /dev/null +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.go b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.go new file mode 100644 index 0000000000000..2a5479e2602af --- /dev/null +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.go @@ -0,0 +1,52 @@ +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} \ No newline at end of file diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.java b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.java new file mode 100644 index 0000000000000..5b8a77b903f45 --- /dev/null +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.java @@ -0,0 +1,38 @@ +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} \ No newline at end of file diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.py b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.py new file mode 100644 index 0000000000000..ae048bfc6c491 --- /dev/null +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.py @@ -0,0 +1,27 @@ +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans diff --git a/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.ts b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.ts new file mode 100644 index 0000000000000..b76038f197900 --- /dev/null +++ b/solution/3500-3599/3503.Longest Palindrome After Substring Concatenation I/Solution.ts @@ -0,0 +1,40 @@ +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +} diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README.md b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README.md index cde9542adaa3c..17ee66466df32 100644 --- a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README.md +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README.md @@ -97,25 +97,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3504.Lo #### Python3 ```python - +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans ``` #### Java ```java - +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; ``` #### Go ```go +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} +``` +#### TypeScript + +```ts +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +} ``` diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README_EN.md b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README_EN.md index 2b86e6af4dd85..3a2e00ef7e1cc 100644 --- a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README_EN.md +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/README_EN.md @@ -95,25 +95,222 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3504.Lo #### Python3 ```python - +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans ``` #### Java ```java - +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; ``` #### Go ```go +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} +``` +#### TypeScript + +```ts +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +} ``` diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.cpp b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.cpp new file mode 100644 index 0000000000000..730bfd925a29d --- /dev/null +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int longestPalindrome(string s, string t) { + int m = s.size(), n = t.size(); + ranges::reverse(t); + vector g1 = calc(s), g2 = calc(t); + int ans = max(ranges::max(g1), ranges::max(g2)); + vector> f(m + 1, vector(n + 1)); + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + +private: + void expand(const string& s, vector& g, int l, int r) { + while (l >= 0 && r < s.size() && s[l] == s[r]) { + g[l] = max(g[l], r - l + 1); + --l; + ++r; + } + } + + vector calc(const string& s) { + int n = s.size(); + vector g(n, 0); + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +}; diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.go b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.go new file mode 100644 index 0000000000000..2a5479e2602af --- /dev/null +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.go @@ -0,0 +1,52 @@ +func longestPalindrome(s, t string) int { + m, n := len(s), len(t) + t = reverse(t) + + g1, g2 := calc(s), calc(t) + ans := max(slices.Max(g1), slices.Max(g2)) + + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s[i-1] == t[j-1] { + f[i][j] = f[i-1][j-1] + 1 + a, b := 0, 0 + if i < m { + a = g1[i] + } + if j < n { + b = g2[j] + } + ans = max(ans, f[i][j]*2+a) + ans = max(ans, f[i][j]*2+b) + } + } + } + return ans +} + +func calc(s string) []int { + n, g := len(s), make([]int, len(s)) + for i := 0; i < n; i++ { + expand(s, g, i, i) + expand(s, g, i, i+1) + } + return g +} + +func expand(s string, g []int, l, r int) { + for l >= 0 && r < len(s) && s[l] == s[r] { + g[l] = max(g[l], r-l+1) + l, r = l-1, r+1 + } +} + +func reverse(s string) string { + r := []rune(s) + slices.Reverse(r) + return string(r) +} \ No newline at end of file diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.java b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.java new file mode 100644 index 0000000000000..5b8a77b903f45 --- /dev/null +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.java @@ -0,0 +1,38 @@ +class Solution { + public int longestPalindrome(String S, String T) { + char[] s = S.toCharArray(); + char[] t = new StringBuilder(T).reverse().toString().toCharArray(); + int m = s.length, n = t.length; + int[] g1 = calc(s), g2 = calc(t); + int ans = Math.max(Arrays.stream(g1).max().getAsInt(), Arrays.stream(g2).max().getAsInt()); + int[][] f = new int[m + 1][n + 1]; + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (s[i - 1] == t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i < m ? g1[i] : 0)); + ans = Math.max(ans, f[i][j] * 2 + (j < n ? g2[j] : 0)); + } + } + } + return ans; + } + + private void expand(char[] s, int[] g, int l, int r) { + while (l >= 0 && r < s.length && s[l] == s[r]) { + g[l] = Math.max(g[l], r - l + 1); + --l; + ++r; + } + } + + private int[] calc(char[] s) { + int n = s.length; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } +} \ No newline at end of file diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.py b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.py new file mode 100644 index 0000000000000..ae048bfc6c491 --- /dev/null +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.py @@ -0,0 +1,27 @@ +class Solution: + def longestPalindrome(self, s: str, t: str) -> int: + def expand(s: str, g: List[int], l: int, r: int): + while l >= 0 and r < len(s) and s[l] == s[r]: + g[l] = max(g[l], r - l + 1) + l, r = l - 1, r + 1 + + def calc(s: str) -> List[int]: + n = len(s) + g = [0] * n + for i in range(n): + expand(s, g, i, i) + expand(s, g, i, i + 1) + return g + + m, n = len(s), len(t) + t = t[::-1] + g1, g2 = calc(s), calc(t) + ans = max(*g1, *g2) + f = [[0] * (n + 1) for _ in range(m + 1)] + for i, a in enumerate(s, 1): + for j, b in enumerate(t, 1): + if a == b: + f[i][j] = f[i - 1][j - 1] + 1 + ans = max(ans, f[i][j] * 2 + (0 if i >= m else g1[i])) + ans = max(ans, f[i][j] * 2 + (0 if j >= n else g2[j])) + return ans diff --git a/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.ts b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.ts new file mode 100644 index 0000000000000..b76038f197900 --- /dev/null +++ b/solution/3500-3599/3504.Longest Palindrome After Substring Concatenation II/Solution.ts @@ -0,0 +1,40 @@ +function longestPalindrome(s: string, t: string): number { + function expand(s: string, g: number[], l: number, r: number): void { + while (l >= 0 && r < s.length && s[l] === s[r]) { + g[l] = Math.max(g[l], r - l + 1); + l--; + r++; + } + } + + function calc(s: string): number[] { + const n = s.length; + const g: number[] = Array(n).fill(0); + for (let i = 0; i < n; i++) { + expand(s, g, i, i); + expand(s, g, i, i + 1); + } + return g; + } + + const m = s.length, + n = t.length; + t = t.split('').reverse().join(''); + const g1 = calc(s); + const g2 = calc(t); + let ans = Math.max(...g1, ...g2); + + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (s[i - 1] === t[j - 1]) { + f[i][j] = f[i - 1][j - 1] + 1; + ans = Math.max(ans, f[i][j] * 2 + (i >= m ? 0 : g1[i])); + ans = Math.max(ans, f[i][j] * 2 + (j >= n ? 0 : g2[j])); + } + } + } + + return ans; +}