A string, each character representing a scene. Between two identical characters is considered to be a continuous scene. For example: abcda, you can think of these five characters as the same scene. Or acafghbeb can think of two aca and beb scenes. If there is a coincidence between the scenes, then the scenes are combined. For example, abcab, where abca and bcab are coincident, then the five characters are considered to be the same scene. Give a string to find the longest scene.
Example
Example 1
Input: "abcda"
Output: 5
Explanation:
The longest scene is "abcda".
Example 2
Input: "abcab"
Output: 5
Explanation:
The longest scene is "abcab".
Notice
1 <= |str| <=1e5- str contains only lowercase letters
First of all, for each character, we note down the position of the rightmost same character it can reach. E.g. abcdad. For character a, the position of the rightmost is 4.
After that, we can form a list of intervals with start and end position of each character. Then the problem is to merge the intervals.
Code (Java):
public class Solution {
/**
* @param str: The scene string
* @return: Return the length longest scene
*/
public int getLongestScene(String str) {
// Write your code here
if (str == null || str.length() == 0) {
return 0;
}
if (str.length() == 1) {
return 1;
}
// pos saves the rightmost position of each character
int[] pos = new int[26];
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
pos[c - 'a'] = i;
}
// store the intervals into the list. Note that it's already sorted by the start time
List<Interval> intervals = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (pos[c - 'a'] != i) {
intervals.add(new Interval(i, pos[c - 'a']));
}
}
// now it's time to merge and get the longest interval
Interval prev = null;
int ans = 1;
for (int i = 0; i < intervals.size(); i++) {
Interval curr = intervals.get(i);
if (prev == null || prev.end < curr.start) {
prev = curr;
} else { // overlap
prev.start = Math.min(prev.start, curr.start);
prev.end = Math.max(prev.end, curr.end);
}
if (prev.end - prev.start + 1 > ans) {
ans = prev.end - prev.start + 1;
}
}
if (prev != null) {
ans = Math.max(ans, prev.end - prev.start + 1);
}
return ans;
}
}
class Interval {
int start;
int end;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
No comments:
Post a Comment