-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy path1520-maximum-number-of-non-overlapping-substrings.js
66 lines (57 loc) · 1.96 KB
/
1520-maximum-number-of-non-overlapping-substrings.js
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
56
57
58
59
60
61
62
63
64
65
66
/**
* 1520. Maximum Number of Non-Overlapping Substrings
* https://leetcode.com/problems/maximum-number-of-non-overlapping-substrings/
* Difficulty: Hard
*
* Given a string s of lowercase letters, you need to find the maximum number of non-empty
* substrings of s that meet the following conditions:
* 1. The substrings do not overlap, that is for any two substrings s[i..j] and s[x..y],
* either j < x or i > y is true.
* 2. A substring that contains a certain character c must also contain all occurrences of c.
*
* Find the maximum number of substrings that meet the above conditions. If there are multiple
* solutions with the same number of substrings, return the one with minimum total length. It
* can be shown that there exists a unique solution of minimum total length.
*
* Notice that you can return the substrings in any order.
*/
/**
* @param {string} s
* @return {string[]}
*/
var maxNumOfSubstrings = function(s) {
const charRange = new Array(26).fill().map(() => [Infinity, -Infinity]);
for (let i = 0; i < s.length; i++) {
const charIndex = s.charCodeAt(i) - 97;
charRange[charIndex][0] = Math.min(charRange[charIndex][0], i);
charRange[charIndex][1] = Math.max(charRange[charIndex][1], i);
}
const intervals = [];
for (let c = 0; c < 26; c++) {
if (charRange[c][0] === Infinity) continue;
const start = charRange[c][0];
let end = charRange[c][1];
let valid = true;
for (let i = start; i <= end; i++) {
const charIndex = s.charCodeAt(i) - 97;
if (charRange[charIndex][0] < start) {
valid = false;
break;
}
end = Math.max(end, charRange[charIndex][1]);
}
if (valid) {
intervals.push([start, end]);
}
}
intervals.sort((a, b) => a[1] - b[1] || a[0] - b[0]);
const result = [];
let lastEnd = -1;
for (const [start, end] of intervals) {
if (start > lastEnd) {
result.push(s.slice(start, end + 1));
lastEnd = end;
}
}
return result;
};