KMP
s1 字符串是否包含 s2 字符串,如果包含返回 s1 中包含 s2 的最左开头位置,不包含返回 -1
暴力方法就是 s1 的每个位置都做开头,然后去匹配 s2 整体,时间复杂度 O(n * m)
KMP 算法可以做到时间复杂度 O(n + m)
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| |
| vector<int> getNextArr(string &p) { |
| int m = p.length(); |
| if (m == 1) return {-1}; |
| vector<int> next(m); |
| |
| next[0] = -1; |
| next[1] = 0; |
| int i = 2; |
| |
| int pre = 0; |
| while (i < m) { |
| if (p[i - 1] == p[pre]) { |
| next[i++] = ++pre; |
| } else if (pre > 0) { |
| |
| pre = next[pre]; |
| } else { |
| next[i++] = 0; |
| } |
| } |
| |
| return next; |
| } |
| |
| |
| int kmp(string &s, string &p) { |
| int n = s.length(); |
| int m = p.length(); |
| |
| vector<int> next = getNextArr(p); |
| |
| |
| int i = 0; |
| |
| int j = 0; |
| |
| while (i < n && j < m) { |
| if (s[i] == p[j]) { |
| i++; |
| j++; |
| } else if (j == 0) { |
| i++; |
| } else { |
| j = next[j]; |
| } |
| } |
| return j == m ? i - m : -1; |
| } |
| |
| int strStr(string haystack, string needle) { |
| return kmp(haystack, needle); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| struct TreeNode { |
| int val; |
| TreeNode *left; |
| TreeNode *right; |
| |
| TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| }; |
| |
| class Solution { |
| public: |
| |
| bool isSame(TreeNode *r1, TreeNode *r2) { |
| if (r1 == nullptr && r2 == nullptr) return true; |
| if (r1 == nullptr || r2 == nullptr) return false; |
| return r1->val == r2->val && isSame(r1->left, r2->left) && isSame(r1->right, r2->right); |
| } |
| |
| |
| bool isSubtree(TreeNode *root, TreeNode *subRoot) { |
| if (root != nullptr && subRoot != nullptr) |
| return isSame(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot); |
| return subRoot == nullptr; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| struct TreeNode { |
| int val; |
| TreeNode *left; |
| TreeNode *right; |
| |
| TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| }; |
| |
| class Solution { |
| public: |
| |
| |
| vector<int> getNextArr(vector<string> &p) { |
| int m = p.size(); |
| if (m == 1) return {-1}; |
| vector<int> next(m); |
| |
| next[0] = -1; |
| next[1] = 0; |
| int i = 2; |
| |
| int pre = 0; |
| while (i < m) { |
| if (p[i - 1] == p[pre]) { |
| next[i++] = ++pre; |
| } else if (pre > 0) { |
| |
| pre = next[pre]; |
| } else { |
| next[i++] = 0; |
| } |
| } |
| |
| return next; |
| } |
| |
| |
| int kmp(vector<string> &s, vector<string> &p) { |
| int n = s.size(); |
| int m = p.size(); |
| |
| vector<int> next = getNextArr(p); |
| |
| |
| int i = 0; |
| |
| int j = 0; |
| |
| while (i < n && j < m) { |
| if (s[i] == p[j]) { |
| i++; |
| j++; |
| } else if (j == 0) { |
| i++; |
| } else { |
| j = next[j]; |
| } |
| } |
| return j == m ? i - m : -1; |
| } |
| |
| |
| void serial(TreeNode *root, vector<string> &path) { |
| if (root == nullptr) { |
| path.emplace_back("null"); |
| return; |
| } |
| path.emplace_back(to_string(root->val)); |
| serial(root->left, path); |
| serial(root->right, path); |
| } |
| |
| |
| bool isSubtree(TreeNode *root, TreeNode *subRoot) { |
| vector<string> s; |
| vector<string> p; |
| serial(root, s); |
| serial(subRoot, p); |
| return kmp(s, p) != -1; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| vector<int> getNextArr(string s) { |
| int n = s.size(); |
| |
| vector<int> next(n + 1); |
| next[0] = -1; |
| next[1] = 0; |
| int i = 2, pre = 0; |
| while (i <= n) { |
| if (s[i - 1] == s[pre]) { |
| next[i++] = ++pre; |
| } else if (pre > 0) { |
| pre = next[pre]; |
| } else { |
| next[i++] = 0; |
| } |
| } |
| return next; |
| } |
| |
| int main() { |
| int n; |
| cin >> n; |
| string s; |
| cin >> s; |
| |
| vector<int> next = getNextArr(s); |
| cout << n - next[n]; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <stack> |
| |
| using namespace std; |
| |
| int MAXN = 1000001; |
| vector<int> nxt(1000001); |
| |
| vector<pair<int, int>> stk(MAXN); |
| |
| int top; |
| |
| void generateNxt(string s) { |
| nxt[0] = -1; |
| int n = s.size(); |
| if (n == 1) return; |
| nxt[1] = 0; |
| int i = 2, pre = 0; |
| while (i < n) { |
| if (s[i - 1] == s[pre]) { |
| nxt[i++] = ++pre; |
| } else if (pre > 0) { |
| pre = nxt[pre]; |
| } else { |
| nxt[i++] = 0; |
| } |
| } |
| } |
| |
| int main() { |
| string s, t; |
| cin >> s >> t; |
| int n = s.length(); |
| int m = t.length(); |
| |
| top = 0; |
| generateNxt(t); |
| |
| int i = 0, j = 0; |
| while (i < n) { |
| if (s[i] == t[j]) { |
| stk[top++] = make_pair(i, j); |
| i++; |
| j++; |
| } else if (j == 0) { |
| stk[top++] = make_pair(i, -1); |
| i++; |
| } else { |
| j = nxt[j]; |
| } |
| if (j == m) { |
| |
| top -= m; |
| |
| |
| j = top > 0 ? stk[top - 1].second + 1 : 0; |
| } |
| } |
| |
| string res = ""; |
| |
| for (int k = 0; k < top; ++k) |
| res += s[stk[k].first]; |
| cout << res; |
| } |
| using namespace std; |
| |
| struct ListNode { |
| int val; |
| ListNode *next; |
| |
| ListNode() : val(0), next(nullptr) {} |
| |
| ListNode(int x) : val(x), next(nullptr) {} |
| |
| ListNode(int x, ListNode *next) : val(x), next(next) {} |
| }; |
| |
| struct TreeNode { |
| int val; |
| TreeNode *left; |
| TreeNode *right; |
| |
| TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| }; |
| |
| class Solution { |
| public: |
| |
| bool dfsJudge(struct TreeNode *root, struct ListNode *head) { |
| if (head == nullptr) return true; |
| if (root == nullptr || root->val != head->val) return false; |
| return dfsJudge(root->left, head->next) || dfsJudge(root->right, head->next); |
| } |
| |
| |
| bool dfs(struct TreeNode *root, struct ListNode *head) { |
| if (root == nullptr) return false; |
| if (dfsJudge(root, head)) return true; |
| return dfs(root->left, head) || dfs(root->right, head); |
| } |
| |
| bool isSubPath(ListNode *head, TreeNode *root) { |
| return dfs(root, head); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| struct ListNode { |
| int val; |
| ListNode *next; |
| |
| ListNode() : val(0), next(nullptr) {} |
| |
| ListNode(int x) : val(x), next(nullptr) {} |
| |
| ListNode(int x, ListNode *next) : val(x), next(next) {} |
| }; |
| |
| struct TreeNode { |
| int val; |
| TreeNode *left; |
| TreeNode *right; |
| |
| TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| |
| TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| }; |
| |
| class Solution { |
| public: |
| |
| void generateNext(ListNode *head, vector<int> &list, vector<int> &next) { |
| |
| while (head != nullptr) { |
| list.emplace_back(head->val); |
| head = head->next; |
| } |
| int n = list.size(); |
| |
| next.resize(n); |
| next[0] = -1; |
| if (n == 1) return; |
| next[1] = 0; |
| int i = 2, pre = 0; |
| while (i < n) { |
| if (list[i - 1] == list[pre]) { |
| next[i++] = ++pre; |
| } else if (pre > 0) { |
| pre = next[pre]; |
| } else { |
| next[i++] = 0; |
| } |
| } |
| } |
| |
| |
| bool dfs(vector<int> &list, vector<int> &next, TreeNode *root, int cur) { |
| if (cur == list.size()) return true; |
| if (root == nullptr) return false; |
| |
| |
| while (cur >= 0 && root->val != list[cur]) |
| cur = next[cur]; |
| |
| |
| return dfs(list, next, root->left, cur + 1) || dfs(list, next, root->right, cur + 1); |
| } |
| |
| |
| bool isSubPath(ListNode *head, TreeNode *root) { |
| vector<int> list; |
| vector<int> next; |
| generateNext(head, list, next); |
| return dfs(list, next, root, 0); |
| } |
| }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步