diff --git a/solution/0600-0699/0645.Set Mismatch/README.md b/solution/0600-0699/0645.Set Mismatch/README.md index ecb85c1a76fef..013c4c3735c37 100644 --- a/solution/0600-0699/0645.Set Mismatch/README.md +++ b/solution/0600-0699/0645.Set Mismatch/README.md @@ -295,29 +295,29 @@ function findErrorNums(nums: number[]): number[] { #### Rust ```rust +use std::collections::HashMap; + impl Solution { pub fn find_error_nums(nums: Vec) -> Vec { - let mut xs = 0; - for (i, x) in nums.iter().enumerate() { - xs ^= ((i + 1) as i32) ^ x; - } - let mut a = 0; - let lb = xs & -xs; - for (i, x) in nums.iter().enumerate() { - if (((i + 1) as i32) & lb) != 0 { - a ^= (i + 1) as i32; - } - if (*x & lb) != 0 { - a ^= *x; - } + let n = nums.len() as i32; + let mut cnt: HashMap = HashMap::new(); + + for &x in &nums { + *cnt.entry(x).or_insert(0) += 1; } - let b = xs ^ a; - for x in nums.iter() { - if *x == a { - return vec![a, b]; + + let mut ans = vec![0; 2]; + + for x in 1..=n { + let c = *cnt.get(&x).unwrap_or(&0); + if c == 2 { + ans[0] = x; + } else if c == 0 { + ans[1] = x; } } - vec![b, a] + + ans } } ``` @@ -477,6 +477,36 @@ function findErrorNums(nums: number[]): number[] { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_error_nums(nums: Vec) -> Vec { + let mut xs = 0; + for (i, x) in nums.iter().enumerate() { + xs ^= ((i + 1) as i32) ^ x; + } + let mut a = 0; + let lb = xs & -xs; + for (i, x) in nums.iter().enumerate() { + if (((i + 1) as i32) & lb) != 0 { + a ^= (i + 1) as i32; + } + if (*x & lb) != 0 { + a ^= *x; + } + } + let b = xs ^ a; + for x in nums.iter() { + if *x == a { + return vec![a, b]; + } + } + vec![b, a] + } +} +``` + diff --git a/solution/0600-0699/0645.Set Mismatch/README_EN.md b/solution/0600-0699/0645.Set Mismatch/README_EN.md index fef38be0dac0a..4b9aeea525b68 100644 --- a/solution/0600-0699/0645.Set Mismatch/README_EN.md +++ b/solution/0600-0699/0645.Set Mismatch/README_EN.md @@ -286,29 +286,29 @@ function findErrorNums(nums: number[]): number[] { #### Rust ```rust +use std::collections::HashMap; + impl Solution { pub fn find_error_nums(nums: Vec) -> Vec { - let mut xs = 0; - for (i, x) in nums.iter().enumerate() { - xs ^= ((i + 1) as i32) ^ x; - } - let mut a = 0; - let lb = xs & -xs; - for (i, x) in nums.iter().enumerate() { - if (((i + 1) as i32) & lb) != 0 { - a ^= (i + 1) as i32; - } - if (*x & lb) != 0 { - a ^= *x; - } + let n = nums.len() as i32; + let mut cnt: HashMap = HashMap::new(); + + for &x in &nums { + *cnt.entry(x).or_insert(0) += 1; } - let b = xs ^ a; - for x in nums.iter() { - if *x == a { - return vec![a, b]; + + let mut ans = vec![0; 2]; + + for x in 1..=n { + let c = *cnt.get(&x).unwrap_or(&0); + if c == 2 { + ans[0] = x; + } else if c == 0 { + ans[1] = x; } } - vec![b, a] + + ans } } ``` @@ -468,6 +468,36 @@ function findErrorNums(nums: number[]): number[] { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_error_nums(nums: Vec) -> Vec { + let mut xs = 0; + for (i, x) in nums.iter().enumerate() { + xs ^= ((i + 1) as i32) ^ x; + } + let mut a = 0; + let lb = xs & -xs; + for (i, x) in nums.iter().enumerate() { + if (((i + 1) as i32) & lb) != 0 { + a ^= (i + 1) as i32; + } + if (*x & lb) != 0 { + a ^= *x; + } + } + let b = xs ^ a; + for x in nums.iter() { + if *x == a { + return vec![a, b]; + } + } + vec![b, a] + } +} +``` + diff --git a/solution/0600-0699/0645.Set Mismatch/Solution2.rs b/solution/0600-0699/0645.Set Mismatch/Solution2.rs index 88cd7e6875d3e..bac645ae363bb 100644 --- a/solution/0600-0699/0645.Set Mismatch/Solution2.rs +++ b/solution/0600-0699/0645.Set Mismatch/Solution2.rs @@ -1,25 +1,25 @@ +use std::collections::HashMap; + impl Solution { pub fn find_error_nums(nums: Vec) -> Vec { - let mut xs = 0; - for (i, x) in nums.iter().enumerate() { - xs ^= ((i + 1) as i32) ^ x; + let n = nums.len() as i32; + let mut cnt: HashMap = HashMap::new(); + + for &x in &nums { + *cnt.entry(x).or_insert(0) += 1; } - let mut a = 0; - let lb = xs & -xs; - for (i, x) in nums.iter().enumerate() { - if (((i + 1) as i32) & lb) != 0 { - a ^= (i + 1) as i32; - } - if (*x & lb) != 0 { - a ^= *x; - } - } - let b = xs ^ a; - for x in nums.iter() { - if *x == a { - return vec![a, b]; + + let mut ans = vec![0; 2]; + + for x in 1..=n { + let c = *cnt.get(&x).unwrap_or(&0); + if c == 2 { + ans[0] = x; + } else if c == 0 { + ans[1] = x; } } - vec![b, a] + + ans } } diff --git a/solution/0600-0699/0645.Set Mismatch/Solution3.rs b/solution/0600-0699/0645.Set Mismatch/Solution3.rs new file mode 100644 index 0000000000000..88cd7e6875d3e --- /dev/null +++ b/solution/0600-0699/0645.Set Mismatch/Solution3.rs @@ -0,0 +1,25 @@ +impl Solution { + pub fn find_error_nums(nums: Vec) -> Vec { + let mut xs = 0; + for (i, x) in nums.iter().enumerate() { + xs ^= ((i + 1) as i32) ^ x; + } + let mut a = 0; + let lb = xs & -xs; + for (i, x) in nums.iter().enumerate() { + if (((i + 1) as i32) & lb) != 0 { + a ^= (i + 1) as i32; + } + if (*x & lb) != 0 { + a ^= *x; + } + } + let b = xs ^ a; + for x in nums.iter() { + if *x == a { + return vec![a, b]; + } + } + vec![b, a] + } +} diff --git a/solution/0600-0699/0647.Palindromic Substrings/README.md b/solution/0600-0699/0647.Palindromic Substrings/README.md index 6a70f44f01466..e6666073a9058 100644 --- a/solution/0600-0699/0647.Palindromic Substrings/README.md +++ b/solution/0600-0699/0647.Palindromic Substrings/README.md @@ -58,7 +58,9 @@ tags: ### 方法一:从中心向两侧扩展回文串 -时间复杂度 $O(n^2)$,其中 $n$ 是字符串 `s` 的长度。 +我们可以枚举回文串的中心位置,然后向两侧扩展,统计回文串的数量。对于长度为 $n$ 的字符串,回文串的中心位置共有 $2n-1$ 个(包括奇数长度和偶数长度的回文串)。对于每个中心位置,我们向两侧扩展,直到不满足回文串的条件为止,统计回文串的数量。 + +时间复杂度 $O(n^2)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(1)$。 @@ -166,7 +168,7 @@ var countSubstrings = function (s) { 在 Manacher 算法的计算过程中,用 $p[i]-1$ 表示以第 $i$ 位为中心的最大回文长度,以第 $i$ 位为中心的回文串数量为 $\left \lceil \frac{p[i]-1}{2} \right \rceil$。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 `s` 的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。 @@ -221,6 +223,130 @@ class Solution { } ``` +#### C++ + +```cpp +class Solution { +public: + int countSubstrings(string s) { + string t = "^#"; + for (char c : s) { + t += c; + t += '#'; + } + t += "$"; + + int n = t.size(); + vector p(n, 0); + int pos = 0, maxRight = 0; + int ans = 0; + + for (int i = 1; i < n - 1; ++i) { + if (maxRight > i) { + p[i] = min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] == t[i + p[i]]) { + ++p[i]; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += p[i] / 2; + } + + return ans; + } +}; +``` + +#### Go + +```go +func countSubstrings(s string) int { + t := "^#" + for _, c := range s { + t += string(c) + t += "#" + } + t += "$" + + n := len(t) + p := make([]int, n) + pos, maxRight := 0, 0 + ans := 0 + + for i := 1; i < n-1; i++ { + if maxRight > i { + mirror := 2*pos - i + if p[mirror] < maxRight-i { + p[i] = p[mirror] + } else { + p[i] = maxRight - i + } + } else { + p[i] = 1 + } + + for t[i-p[i]] == t[i+p[i]] { + p[i]++ + } + + if i+p[i] > maxRight { + maxRight = i + p[i] + pos = i + } + + ans += p[i] / 2 + } + + return ans +} +``` + +#### TypeScript + +```ts +function countSubstrings(s: string): number { + let t = "^#"; + for (const c of s) { + t += c + "#"; + } + t += "$"; + + const n = t.length; + const p: number[] = new Array(n).fill(0); + let pos = 0, maxRight = 0; + let ans = 0; + + for (let i = 1; i < n - 1; i++) { + if (maxRight > i) { + p[i] = Math.min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] === t[i + p[i]]) { + p[i]++; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += Math.floor(p[i] / 2); + } + + return ans; +} +``` + diff --git a/solution/0600-0699/0647.Palindromic Substrings/README_EN.md b/solution/0600-0699/0647.Palindromic Substrings/README_EN.md index 3ed7a61228e9a..6cff9ad78fb26 100644 --- a/solution/0600-0699/0647.Palindromic Substrings/README_EN.md +++ b/solution/0600-0699/0647.Palindromic Substrings/README_EN.md @@ -55,7 +55,11 @@ tags: -### Solution 1 +### Solution 1: Expand Around Center + +We can enumerate the center position of each palindrome and expand outward to count the number of palindromic substrings. For a string of length $n$, there are $2n-1$ possible center positions (covering both odd-length and even-length palindromes). For each center, we expand outward until the palindrome condition is no longer satisfied, and count the number of palindromic substrings. + +The time complexity is $O(n^2)$, where $n$ is the length of string $s$. The space complexity is $O(1)$. @@ -159,7 +163,11 @@ var countSubstrings = function (s) { -### Solution 2 +### Solution 2: Manacher's Algorithm + +In Manacher's algorithm, $p[i] - 1$ represents the maximum palindrome length centered at position $i$, and the number of palindromic substrings centered at position $i$ is $\left \lceil \frac{p[i]-1}{2} \right \rceil$. + +The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the length of string $s$. @@ -214,6 +222,130 @@ class Solution { } ``` +#### C++ + +```cpp +class Solution { +public: + int countSubstrings(string s) { + string t = "^#"; + for (char c : s) { + t += c; + t += '#'; + } + t += "$"; + + int n = t.size(); + vector p(n, 0); + int pos = 0, maxRight = 0; + int ans = 0; + + for (int i = 1; i < n - 1; ++i) { + if (maxRight > i) { + p[i] = min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] == t[i + p[i]]) { + ++p[i]; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += p[i] / 2; + } + + return ans; + } +}; +``` + +#### Go + +```go +func countSubstrings(s string) int { + t := "^#" + for _, c := range s { + t += string(c) + t += "#" + } + t += "$" + + n := len(t) + p := make([]int, n) + pos, maxRight := 0, 0 + ans := 0 + + for i := 1; i < n-1; i++ { + if maxRight > i { + mirror := 2*pos - i + if p[mirror] < maxRight-i { + p[i] = p[mirror] + } else { + p[i] = maxRight - i + } + } else { + p[i] = 1 + } + + for t[i-p[i]] == t[i+p[i]] { + p[i]++ + } + + if i+p[i] > maxRight { + maxRight = i + p[i] + pos = i + } + + ans += p[i] / 2 + } + + return ans +} +``` + +#### TypeScript + +```ts +function countSubstrings(s: string): number { + let t = "^#"; + for (const c of s) { + t += c + "#"; + } + t += "$"; + + const n = t.length; + const p: number[] = new Array(n).fill(0); + let pos = 0, maxRight = 0; + let ans = 0; + + for (let i = 1; i < n - 1; i++) { + if (maxRight > i) { + p[i] = Math.min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] === t[i + p[i]]) { + p[i]++; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += Math.floor(p[i] / 2); + } + + return ans; +} +``` + diff --git a/solution/0600-0699/0647.Palindromic Substrings/Solution2.cpp b/solution/0600-0699/0647.Palindromic Substrings/Solution2.cpp new file mode 100644 index 0000000000000..6530192b9a4f4 --- /dev/null +++ b/solution/0600-0699/0647.Palindromic Substrings/Solution2.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + int countSubstrings(string s) { + string t = "^#"; + for (char c : s) { + t += c; + t += '#'; + } + t += "$"; + + int n = t.size(); + vector p(n, 0); + int pos = 0, maxRight = 0; + int ans = 0; + + for (int i = 1; i < n - 1; ++i) { + if (maxRight > i) { + p[i] = min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] == t[i + p[i]]) { + ++p[i]; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += p[i] / 2; + } + + return ans; + } +}; diff --git a/solution/0600-0699/0647.Palindromic Substrings/Solution2.go b/solution/0600-0699/0647.Palindromic Substrings/Solution2.go new file mode 100644 index 0000000000000..243c2631ab3bd --- /dev/null +++ b/solution/0600-0699/0647.Palindromic Substrings/Solution2.go @@ -0,0 +1,39 @@ +func countSubstrings(s string) int { + t := "^#" + for _, c := range s { + t += string(c) + t += "#" + } + t += "$" + + n := len(t) + p := make([]int, n) + pos, maxRight := 0, 0 + ans := 0 + + for i := 1; i < n-1; i++ { + if maxRight > i { + mirror := 2*pos - i + if p[mirror] < maxRight-i { + p[i] = p[mirror] + } else { + p[i] = maxRight - i + } + } else { + p[i] = 1 + } + + for t[i-p[i]] == t[i+p[i]] { + p[i]++ + } + + if i+p[i] > maxRight { + maxRight = i + p[i] + pos = i + } + + ans += p[i] / 2 + } + + return ans +} diff --git a/solution/0600-0699/0647.Palindromic Substrings/Solution2.ts b/solution/0600-0699/0647.Palindromic Substrings/Solution2.ts new file mode 100644 index 0000000000000..16e88c0715dc3 --- /dev/null +++ b/solution/0600-0699/0647.Palindromic Substrings/Solution2.ts @@ -0,0 +1,33 @@ +function countSubstrings(s: string): number { + let t = "^#"; + for (const c of s) { + t += c + "#"; + } + t += "$"; + + const n = t.length; + const p: number[] = new Array(n).fill(0); + let pos = 0, maxRight = 0; + let ans = 0; + + for (let i = 1; i < n - 1; i++) { + if (maxRight > i) { + p[i] = Math.min(maxRight - i, p[2 * pos - i]); + } else { + p[i] = 1; + } + + while (t[i - p[i]] === t[i + p[i]]) { + p[i]++; + } + + if (i + p[i] > maxRight) { + maxRight = i + p[i]; + pos = i; + } + + ans += Math.floor(p[i] / 2); + } + + return ans; +}