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
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; } }