Java C++ 算法leetcode828統計子串中唯一字符乘法原理
題目要求
思路:模擬
解題的核心思想在於逆向思維,不考慮每個子數組中的唯一字符個數,轉而考慮每個字符可以作為多少個子數組的唯一字符;
- 所以在計算答案時的算式和示例中給出的是不一樣的;
- 在計算每個字符“貢獻”【即當前向左向右分別可組成的答案個數】的時候要用到乘法原理。
對每一個字符s[i]s[i]s[i]都記錄其左邊和右邊的第一個相同字符位置,分別記為l[i]l[i]l[i]和r[i]r[i]r[i],這兩個位置中間構成的就是s[i]s[i]s[i]能夠作為唯一字符的最長子串,在這個最長的子串中還有若幹個較短的子串,此時s[i]s[i]s[i]的“貢獻”可由到左邊和到右邊的距離相乘計算得出。
java
class Solution { public int uniqueLetterString(String s) { char[] cs = s.toCharArray(); int n = cs.length, res = 0; int[] l = new int[n], r = new int[n]; int[] letters = new int[26]; Arrays.fill(letters, -1); for (int i = 0; i < n; i++) { int idx = cs[i] - 'A'; l[i] = letters[idx]; // 左邊第一個相同的字符所在位置 letters[idx] = i; // 更新當前字母最新左位置 } Arrays.fill(letters, n); for (int i = n - 1; i >= 0; i--) { int idx = cs[i] - 'A'; r[i] = letters[idx]; // 右邊第一個相同的字符所在位置 letters[idx] = i; // 更新當前字母最新右位置 } for (int i = 0; i < n; i++) res += (i - l[i]) * (r[i] - i); return res; } }
- 時間復雜度:O(n)
- 空間復雜度:O(n)
C++
- 因為
memset
初始化問題,所以在構成結果的時候多一步判斷。
class Solution { public: int uniqueLetterString(string s) { int n = s.size(), res = 0; cout << n << endl; int l[n], r[n]; int letters[26]; memset(letters, -1, sizeof(letters)); for (int i = 0; i < n; i++) { int idx = s[i] - 'A'; l[i] = letters[idx]; // 左邊第一個相同的字符所在位置 letters[idx] = i; // 更新當前字母最新左位置 } memset(letters, -1, sizeof(letters)); for (int i = n - 1; i >= 0; i--) { int idx = s[i] - 'A'; r[i] = letters[idx]; // 右邊第一個相同的字符所在位置 letters[idx] = i; // 更新當前字母最新右位置 } for (int i = 0; i < n; i++) { int ri = r[i] == -1 ? n : r[i]; res += (i - l[i]) * (ri - i); } return res; } };
- 時間復雜度:O(n)
- 空間復雜度:O(n)
Rust
- 用Rust的遍歷稍微改一下,思路一樣……
impl Solution { pub fn unique_letter_string(s: String) -> i32 { let cs = s.as_bytes(); (0..s.len()).into_iter().map(|i| { let (mut l, mut r) = (i - 1, i + 1); while l < s.len() && cs[l] != cs[i] { l -= 1; } while r < s.len() && cs[r] != cs[i] { r += 1; } ((i - l) * (r - i)) as i32 }).sum::<i32>() } }
- 時間復雜度:O(n)
- 空間復雜度:O(n)
以上就是Java C++ 算法leetcode828統計子串中唯一字符乘法原理的詳細內容,更多關於Java C++ 統計子串唯一字符的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Java C++ 算法題解leetcode145商品折扣後最終價格單調棧
- Java C++ 算法題解leetcode1582二進制矩陣特殊位置
- Java C++算法題解leetcode801使序列遞增的最小交換次數
- Java C++題解leetcode915分割數組示例
- C++實現LeetCode(17.電話號碼的字母組合)