1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Solution {
public:
vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) {
int n = s.size(), k = queryCharacters.size();
map<int, int> m; // {{left, right}}
multiset<int> ms; // {length}
for (int i = 0; i < n;) {
int j = i + 1;
while (j < n && s[j] == s[i]) ++j;
m[i] = j - 1;
ms.insert(j - i);
i = j;
}
// cut from pos `left` if `left` is not a start of certain range.
auto cut = [&](int left)-> void {
if (left < 0 || left >= n) return;
if (!m.count(left)) {
// get the range that contains `left`.
auto [l, r] = *prev(m.lower_bound(left));
ms.extract(r - l + 1);
// split into two ranges, [l, left - 1], [left, r].
m[l] = left - 1;
m[left] = r;
ms.insert(left - l);
ms.insert(r - left + 1);
}
};
// join the range that starts with `left` with its prev range if possible.
auto join = [&](int left) -> void {
if (left <= 0 || left >= n) return;
auto [pl, pr] = *prev(m.lower_bound(left));
if (s[pl] == s[left]) {
ms.extract(pr - pl + 1);
ms.extract(m[left] - left + 1);
ms.insert(m[left] - pl + 1);
m[pl] = m[left];
m.erase(left);
}
};
vector<int> ans(k);
for (int i = 0; i < k; ++i) {
int left = queryIndices[i];
char ch = queryCharacters[i];
if (s[left] != ch) {
s[left] = ch;
cut(left), cut(left + 1);
join(left), join(left + 1);
}
ans[i] = *ms.rbegin();
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
public:
string s;
struct Node {
int l, r, prefix, suffix, val;
Node() {}
Node(int l, int r) : l(l), r(r), prefix(1), suffix(1), val(1) {}
} tr[400000];
void build(int u, int l, int r) {
tr[u] = {l, r};
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}
void update(int u, int i, char c) {
if (tr[u].l == i && tr[u].r == i) {
s[i - 1] = c;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (i <= mid) update(u << 1, i, c);
else update(u << 1 | 1, i, c);
pushup(u);
}
void pushup(int u) {
auto left = tr[u << 1], right = tr[u << 1 | 1];
int leftLen = left.r - left.l + 1, rightLen = right.r - right.l + 1;
char leftLast = s[left.r - 1], rightFirst = s[right.l - 1];
tr[u].prefix = left.prefix, tr[u].suffix = right.suffix, tr[u].val = max(left.val, right.val);
if (leftLast == rightFirst) {
if (left.prefix == leftLen) tr[u].prefix = leftLen + right.prefix;
if (right.prefix == rightLen) tr[u].suffix = left.suffix + rightLen;
tr[u].val = max(tr[u].val, left.suffix + right.prefix);
}
}
int query(int u, int l, int r) {
if (l <= tr[u].l && tr[u].r <= r) return tr[u].val;
int ans = 0, mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) ans = query(u << 1, l, r);
if (r > mid) ans = max(ans, query(u << 1 | 1, l, r));
return ans;
}
vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) {
int n = s.size(), k = queryIndices.size();
this->s = s;
build(1, 1, n);
for (int i = 0; i < n; ++i) update(1, i + 1, s[i]);
vector<int> ans(k);
for (int i = 0; i < k; ++i) {
update(1, queryIndices[i] + 1, queryCharacters[i]);
ans[i] = query(1, 1, n);
}
return ans;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class SummaryRanges {
map<int, int> m;
public:
SummaryRanges() {}

void addNum(int val) {
int left = val, right = val;
for (auto it = m.lower_bound(val - 1); it != m.end() && it->second <= right + 1; m.erase(it++)) {
int l = it->second, r = it->first;
left = min(left, l), right = max(right, r);
}
m[right] = left;
}

vector<vector<int>> getIntervals() {
vector<vector<int>> v;
for (auto it = m.begin(); it != m.end(); ++it)
v.push_back({it->second, it->first});
return v;
}
};

/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges* obj = new SummaryRanges();
* obj->addNum(val);
* vector<vector<int>> param_2 = obj->getIntervals();
*/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class RangeModule {
map<int, int> m;
public:
RangeModule() {}

void addRange(int left, int right) {
for (auto it = m.lower_bound(left); it != m.end() && it->second <= right; m.erase(it++)) {
int l = it->second, r = it->first;
left = min(left, l), right = max(right, r);
}
m[right] = left;
}

bool queryRange(int left, int right) {
auto it = m.lower_bound(left);
return it != m.end() && it->second <= left && it->first >= right;
}

void removeRange(int left, int right) {
for (auto it = m.lower_bound(left + 1); it != m.end() && it->second <= right;) {
if (it->second < left) {
m[left] = it->second;
}
if (it->first > right) {
m[it->first] = right;
break;
} else m.erase(it++);
}
}
};

/**
* Your RangeModule object will be instantiated and called as such:
* RangeModule* obj = new RangeModule();
* obj->addRange(left,right);
* bool param_2 = obj->queryRange(left,right);
* obj->removeRange(left,right);
*/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class CountIntervals {
map<int, int> m;
int cnt = 0;
public:
CountIntervals() {}

void add(int left, int right) {
for (auto it = m.lower_bound(left); it != m.end() && it->second <= right; m.erase(it++)) {
int l = it->second, r = it->first;
left = min(left, l), right = max(right, r);
cnt -= r - l + 1;
}
cnt += right - left + 1;
m[right] = left;
}

int count() {
return cnt;
}
};

/**
* Your CountIntervals object will be instantiated and called as such:
* CountIntervals* obj = new CountIntervals();
* obj->add(left,right);
* int param_2 = obj->count();
*/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if (n < 2) return n;
int up[n], down[n];
up[0] = down[0] = 1;
for (int i = 1; i < n; ++i) {
if (nums[i] > nums[i - 1])
up[i] = max(up[i - 1], down[i - 1] + 1), down[i] = down[i - 1];
else if (nums[i] < nums[i - 1])
down[i] = max(down[i - 1], up[i - 1] + 1), up[i] = up[i - 1];
else
up[i] = up[i - 1], down[i] = down[i - 1];
}
return max(up[n - 1], down[n - 1]);
}
};
1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size(), up = 1, down = 1;
for (int i = 1; i < n; ++i) {
if (nums[i] > nums[i - 1]) up = max(up, down + 1);
else if (nums[i] < nums[i - 1]) down = max(down, up + 1);
}
return max(up, down);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if (n < 2) return n;
int preDiff = nums[1] - nums[0],
ans = preDiff != 0 ? 2 : 1;
for (int i = 1; i < n; ++i) {
int diff = nums[i] - nums[i - 1];
if (diff > 0 && preDiff <= 0 ||
diff < 0 && preDiff >= 0)
++ans, preDiff = diff;
}
return ans;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int kConcatenationMaxSum(vector<int>& arr, int k) {
int n = arr.size(), sum = arr[0], maxSum = arr[0];
int64_t total = accumulate(arr.begin(), arr.end(), 0), mod = 1e9 + 7;
for (int i = 1; i < n * min(k, 2); ++i) {
if (sum > 0) sum += arr[i % n];
else sum = arr[i % n];
maxSum = max(maxSum, sum);
}
return max<int64_t>({0, maxSum, total * max(0, k - 2) + maxSum}) % mod;
}
};

Reference: Short and concise O(N) C++ solution - LeetCode Discuss.

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
int maximumSum(vector<int>& arr) {
int n = arr.size(), deleted = 0, reserved = arr[0], ans = arr[0];
for (int i = 1; i < n; ++i) {
deleted = max(deleted + arr[i], reserved);
reserved = max(reserved + arr[i], arr[i]);
ans = max(ans, max(deleted, reserved));
}
return ans;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int maxProduct(vector<int>& nums) {
int minProduct = nums[0], maxProduct = nums[0], ans = nums[0];
for (int i = 1; i < nums.size(); ++i) {
int m1 = minProduct, m2 = maxProduct;
maxProduct = max(max(nums[i], m1 * nums[i]), m2 * nums[i]);
minProduct = min(min(nums[i], m1 * nums[i]), m2 * nums[i]);
ans = max(ans, maxProduct);
}
return ans;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
int largestVariance(string s) {
int ans = 0;
unordered_set<char> unique(s.begin(), s.end());
// go through each possibilities to find the ans.
for (char a : unique)
for (char b : unique) {
if (a == b) continue;
int var = 0, has_b = 0, first_b = 0;
for (auto ch : s) {
// var is used to track the occurrences diff between "a" and "b".
if (ch == a) ++var;
else if (ch == b) {
has_b = true;
// we are having a leading "b" and now one more "b" with cnt(a) >= cnt(b),
// so we can cut the leading "b" for a better ans.
if (first_b && var >= 0) first_b = false;
// "--var < 0" indicates that we are having too many "b(s)" here,
// so we take this "b" as a fresh start.
else if (--var < 0) first_b = true, var = -1;
}
// update the ans if and only if "b" is within the substr.
ans = max(ans, has_b ? var : 0);
}
}
return ans;
}
};

Reference: Weird Kadane - LeetCode Discuss.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int maximumWhiteTiles(int[][] tiles, int carpetLen) {
Arrays.sort(tiles, (a, b) -> a[0] - b[0]);
int n = tiles.length, ans = 0;
for (int l = 0, r = 0, s = 0; r < n; ++l) {
while (r < n && tiles[r][1] - tiles[l][0] + 1 <= carpetLen) {
s += tiles[r][1] - tiles[r][0] + 1;
++r;
}
if (r == n) ans = Math.max(ans, s);
else {
int coveredPath = Math.max(tiles[l][0] + carpetLen - tiles[r][0], 0);
ans = Math.max(ans, coveredPath + s);
s -= tiles[l][1] - tiles[l][0] + 1;
}
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int maximumWhiteTiles(int[][] tiles, int carpetLen) {
Arrays.sort(tiles, (a, b) -> a[0] - b[0]);
int n = tiles.length, ans = 0;
for (int l = 0, r = 0, s = 0; r < n;) {
int leftBoundary = tiles[l][0], rightBoundary = leftBoundary + carpetLen - 1;
if (tiles[r][1] <= rightBoundary) { // covered.
s += tiles[r][1] - tiles[r][0] + 1;
ans = Math.max(ans, s);
++r;
} else {
if (rightBoundary > tiles[r][0]) // partially covered.
ans = Math.max(ans, s + rightBoundary - tiles[r][0] + 1);
s -= tiles[l][1] - tiles[l][0] + 1;
++l;
}
}
return ans;
}
}
0%