From 5f6aa846a24c16d53287143a9ae5198c536fea23 Mon Sep 17 00:00:00 2001 From: zhuyijun Date: Thu, 23 Dec 2021 15:41:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E7=BB=84=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- list/167.cpp | 57 +++++++++++++++++++ list/283.cpp | 25 ++++++++ string/1044.cpp | 147 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 list/167.cpp create mode 100644 list/283.cpp create mode 100644 string/1044.cpp diff --git a/list/167.cpp b/list/167.cpp new file mode 100644 index 0000000..25b0e3e --- /dev/null +++ b/list/167.cpp @@ -0,0 +1,57 @@ +/* + * @Description: + * @Version: 1.0 + * @Autor: zhuyijun + * @Date: 2021-12-23 15:37:34 + * @LastEditTime: 2021-12-23 15:41:18 + */ +/* +167. 两数之和 II - 输入有序数组 + +给定一个已按照 非递减顺序排列 的整数数组 numbers +,请你从数组中找出两个数满足相加之和等于目标数 target 。 + +函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 +开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。 + +你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。 + + +示例 1: + +输入:numbers = [2,7,11,15], target = 9 +输出:[1,2] +解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 + +示例 2: + +输入:numbers = [2,3,4], target = 6 +输出:[1,3] + +示例 3: + +输入:numbers = [-1,0], target = -1 +输出:[1,2] + + + +*/ +#include +using namespace std; +vector twoSum(vector& numbers, int target) { + int l = 0, r = numbers.size() - 1; + while (l < r) { + if (numbers[l] + numbers[r] == target) { + int ret[] = {l + 1, r + 1}; + return vector(ret, ret + 2); + } + if (numbers[l] + numbers[r] < target) { + l++; + } else { + r--; + } + } + return vector(); +} + +int main() { return 0; } \ No newline at end of file diff --git a/list/283.cpp b/list/283.cpp new file mode 100644 index 0000000..9a9de5b --- /dev/null +++ b/list/283.cpp @@ -0,0 +1,25 @@ +/* + * @Description: + * @Version: 1.0 + * @Autor: zhuyijun + * @Date: 2021-12-23 15:28:42 + * @LastEditTime: 2021-12-23 15:29:45 + */ +#include +using namespace std; +void moveZeroes(vector& nums) { + if (nums.size() <= 1) { + return; + } + int index = 0; + for (int i = 0; i < nums.size(); i++) { + if (nums[i] != 0) { + nums[index] = nums[i]; + index++; + } + } + while (index < nums.size()) { + nums[index++] = 0; + } +} +int main() { return 0; } \ No newline at end of file diff --git a/string/1044.cpp b/string/1044.cpp new file mode 100644 index 0000000..6d9c2de --- /dev/null +++ b/string/1044.cpp @@ -0,0 +1,147 @@ +/* + * @Description: + * @Version: 1.0 + * @Autor: zhuyijun + * @Date: 2021-12-23 14:37:52 + * @LastEditTime: 2021-12-23 14:37:52 + */ +/* +1044. 最长重复子串 + +给你一个字符串 s ,考虑其所有 重复子串 :即,s 的连续子串,在 s 中出现 2 +次或更多次。这些出现之间可能存在重叠。 + +返回 任意一个 可能具有最长长度的重复子串。如果 s 不含重复子串,那么答案为 "" 。 + +示例 1: + +输入:s = "banana" +输出:"ana" + +示例 2: + +输入:s = "abcd" +输出:"" + +*/ +class SuffixArray { + public: + using size_type = unsigned; + using pointer = size_type*; + using const_pointer = const size_type*; + const_pointer sa, rk, ht; + + private: + std::unique_ptr data; + + private: + template + inline static bool substring_equal(const S& s, size_type p1, size_type p2, + size_type len) { + for (size_type i = 0; i < len; ++i) + if (s[p1 + i] != s[p2 + i]) return false; + return true; + } + + template + inline static void induced_sort(const S& s, pointer sa, bool* type, + pointer pos, pointer lbuk, pointer sbuk, + size_type n, size_type m, size_type n0) { + std::fill_n(sa, n, 0); + lbuk[0] = 0; + for (size_type i = 1; i < m; ++i) lbuk[i] = sbuk[i - 1]; + for (size_type i = n0; i-- > 0;) sa[--sbuk[s[pos[i]]]] = pos[i]; + sbuk[m - 1] = n; + for (size_type i = 1; i < m; ++i) sbuk[i - 1] = lbuk[i]; + sa[lbuk[s[n - 1]]++] = n - 1; + for (size_type i = 0; i < n; ++i) + if (sa[i] > 0 && !type[sa[i] - 1]) sa[lbuk[s[sa[i] - 1]]++] = sa[i] - 1; + lbuk[0] = 0; + for (size_type i = 1; i < m; ++i) lbuk[i] = sbuk[i - 1]; + for (size_type i = n; i-- > 0;) + if (sa[i] > 0 && type[sa[i] - 1]) sa[--sbuk[s[sa[i] - 1]]] = sa[i] - 1; + } + + template + inline static void sais(const S& s, pointer sa, bool* type, pointer len, + pointer pos, pointer lbuk, pointer sbuk, size_type n, + size_type m) { + type[n - 1] = false; + for (size_type i = n - 1; i-- > 0;) + type[i] = s[i] != s[i + 1] ? s[i] < s[i + 1] : type[i + 1]; + size_type n0 = 0; + for (size_type i = 1; i < n; ++i) + if (!type[i - 1] && type[i]) pos[n0++] = i; + std::fill_n(len, n, 0); + for (size_type p = n - 1, i = n0; i-- > 0; p = pos[i]) + len[pos[i]] = p - pos[i] + 1; + std::fill_n(sbuk, m, 0); + for (size_type i = 0; i < n; ++i) ++sbuk[s[i]]; + for (size_type i = 1; i < m; ++i) sbuk[i] += sbuk[i - 1]; + induced_sort(s, sa, type, pos, lbuk, sbuk, n, m, n0); + sbuk[m - 1] = n; + for (size_type i = 1; i < m; ++i) sbuk[i - 1] = lbuk[i]; + size_type m0 = -1; + size_type ppos = -1, plen = 0; + for (size_type i = 0; i < n; ++i) { + if (len[sa[i]] == 0) continue; + if (len[sa[i]] != plen || !substring_equal(s, sa[i], ppos, plen)) ++m0; + plen = len[sa[i]]; + len[sa[i]] = m0; + ppos = sa[i]; + } + pointer s0 = sa; + pointer sa0 = sa + n0; + for (size_type i = 0; i < n0; ++i) s0[i] = len[pos[i]]; + if (++m0 < n0) + sais(s0, sa0, type + n, len, pos + n0, lbuk, lbuk + n0, n0, m0); + else + for (size_type i = 0; i < n0; ++i) sa0[s0[i]] = i; + for (size_type i = 0; i < n0; ++i) pos[i + n0] = pos[sa0[i]]; + induced_sort(s, sa, type, pos + n0, lbuk, sbuk, n, m, n0); + } + + public: + template + SuffixArray(const S& s, size_type n, size_type m) + : data(std::make_unique(3 * n)) { + const auto type = std::make_unique(2 * n); + const auto lbuk = std::make_unique(std::max(n, m)); + const auto sbuk = std::make_unique(m); + pointer sa = data.get(), rk = sa + n, ht = rk + n; + sais(s, sa, type.get(), rk, ht, lbuk.get(), sbuk.get(), n, m); + for (size_type i = 0; i < n; ++i) rk[sa[i]] = i; + for (size_type k = 0, i = 0; i < n; ++i) { + if (rk[i] == 0) continue; + if (k > 0) --k; + for (size_type j = sa[rk[i] - 1], l = n - std::max(i, j); k < l; ++k) + if (s[i + k] != s[j + k]) break; + ht[rk[i]] = k; + } + this->sa = sa; + this->rk = rk; + this->ht = ht; + } + + size_type suffix(size_type p) const { return sa[p]; } + + size_type rank(size_type p) const { return rk[p]; } + + size_type height(size_type p) const { return ht[p]; } +}; + +class Solution { + public: + string longestDupSubstring(string s) { + const int n = s.size(); + SuffixArray sa(s.c_str(), n, 128); + int len = 0, pos = -1; + for (int i = 1; i < n; ++i) { + if (sa.ht[i] > len) { + len = sa.ht[i]; + pos = sa.sa[i]; + } + } + return pos == -1 ? "" : s.substr(pos, len); + } +}; \ No newline at end of file