add: 221022
This commit is contained in:
parent
542023aa38
commit
ab8c056b6d
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 76. Minimum Window Substring
|
||||||
|
*
|
||||||
|
* Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
|
||||||
|
* The testcases will be generated such that the answer is unique.
|
||||||
|
* A substring is a contiguous sequence of characters within the string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
private:
|
||||||
|
static inline int pos_of(char ch) {
|
||||||
|
return (ch > 'Z') ? (ch - 'a') : (ch - 'A' + 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::string minWindow(const std::string& s, const std::string& t) {
|
||||||
|
int m = s.length(), n = t.length();
|
||||||
|
const char* sp = s.c_str();
|
||||||
|
const char* tp = t.c_str();
|
||||||
|
if (m < n)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
int seg_tree[128]{};
|
||||||
|
for (int i = 0; i < m; ++i)
|
||||||
|
++seg_tree[pos_of(sp[i])];
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
++seg_tree[64 + pos_of(tp[i])];
|
||||||
|
for (int i = 0; i < 52; ++i)
|
||||||
|
if (seg_tree[i] < seg_tree[64 + i])
|
||||||
|
return "";
|
||||||
|
|
||||||
|
// Initial build of seg tree
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
--seg_tree[64 + pos_of(sp[i])];
|
||||||
|
for (int i = 64; --i; )
|
||||||
|
seg_tree[i] = std::max(seg_tree[i << 1], seg_tree[i << 1 | 1]);
|
||||||
|
if (seg_tree[1] <= 0)
|
||||||
|
return s.substr(0, n);
|
||||||
|
|
||||||
|
// gradually expand & shrink
|
||||||
|
int L = 0, R = n, minL = 0x7FFFFFFF, mL, mR; // L inclusive, R exclusive
|
||||||
|
std::string ret;
|
||||||
|
while (R < m) {
|
||||||
|
// R+
|
||||||
|
for (; R < m && seg_tree[1] > 0; ++R) {
|
||||||
|
int p = pos_of(sp[R]) + 64;
|
||||||
|
--seg_tree[p];
|
||||||
|
// Update tree
|
||||||
|
while (p >>= 1)
|
||||||
|
seg_tree[p] = std::max(seg_tree[p << 1], seg_tree[p << 1 | 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// L+
|
||||||
|
for (; L + n <= R; ++L) {
|
||||||
|
int p = pos_of(sp[L]) + 64;
|
||||||
|
if (seg_tree[p] >= 0)
|
||||||
|
break;
|
||||||
|
++seg_tree[p];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update tree after L+ at once
|
||||||
|
for (int i = 64; --i; )
|
||||||
|
seg_tree[i] = std::max(seg_tree[i << 1], seg_tree[i << 1 | 1]);
|
||||||
|
|
||||||
|
if (seg_tree[1] <= 0 && minL > R - L && R - L > 0)
|
||||||
|
minL = (mR = R) - (mL = L);
|
||||||
|
|
||||||
|
// Force update L
|
||||||
|
int p = pos_of(sp[L++]) + 64;
|
||||||
|
++seg_tree[p];
|
||||||
|
while (p >>= 1)
|
||||||
|
seg_tree[p] = std::max(seg_tree[p << 1], seg_tree[p << 1 | 1]);
|
||||||
|
}
|
||||||
|
return s.substr(mL, mR - mL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << Solution::minWindow("acbdbaab", "aabd") << "\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -3,4 +3,4 @@ PROJECT(2210)
|
||||||
|
|
||||||
SET(CMAKE_CXX_STANDARD 23)
|
SET(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
ADD_EXECUTABLE(2210 221022-CN.cpp)
|
ADD_EXECUTABLE(2210 221022.cpp)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue