import java.util.*;
/**
* NC355 划分字母区间
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return int整型ArrayList
*/
public ArrayList<Integer> splitString (String s) {
// return solution1(s);
// return solution2(s);
// return solution3(s);
return solution4(s);
}
/**
* 贪心+双指针+字符串
* @param s
* @return
*/
private ArrayList<Integer> solution3(String s){
int n = s.length();
ArrayList<Integer> result = new ArrayList<>();
// 双指针
int left = 0;
int right = 0;
int pre = -1;
while(left < n){
// 贪心
right = Math.max(right, s.lastIndexOf(s.charAt(left)));
if(left == right){
result.add(right-pre);
pre = right;
}
left++;
}
return result;
}
/**
* 贪心+双指针+哈希
* @param s
* @return
*/
private ArrayList<Integer> solution4(String s){
int n = s.length();
// 哈希 字符:最右索引
HashMap<Character, Integer> rightIndexMap = new HashMap<>();
char ch;
for(int i=n-1; i>=0; i--){
ch = s.charAt(i);
if(!rightIndexMap.keySet().contains(ch)){
rightIndexMap.put(ch, i);
}
}
ArrayList<Integer> result = new ArrayList<>();
// 双指针
int left = 0;
int right = 0;
for(int i=0; i<n; i++){
ch = s.charAt(i);
// 贪心
right = Math.max(right, rightIndexMap.get(ch));
if(i == right){
result.add(right-left+1);
left = i+1;
}
}
return result;
}
//////////////////////////////////////////////////////////////////////////
/**
* Single HashMap
* @param s
* @return
*/
private ArrayList<Integer> solution1(String s){
HashMap<Character, Integer> rightMap = new HashMap<>();
int len = s.length();
for(int i=0,j=len-1; i<len&&j>=0; i++,j--){
if(!rightMap.keySet().contains(s.charAt(j))){
rightMap.put(s.charAt(j), j);
}
}
ArrayList<Integer> list = new ArrayList<Integer>();
int left=0,right=0;
char ch;
for(int i=0; i<len; i++){
ch = s.charAt(i);
right = Math.max(right, rightMap.get(ch));
if(i == right){
list.add(right-left+1);
left = i+1;
}
}
return list;
}
/**
* Double HashMap
* @param s
* @return
*/
private ArrayList<Integer> solution2(String s){
HashMap<Character, Integer> leftMap = new HashMap<>();
HashMap<Character, Integer> rightMap = new HashMap<>();
int len = s.length();
for(int i=0,j=len-1; i<len&&j>=0; i++,j--){
if(!leftMap.keySet().contains(s.charAt(i))){
leftMap.put(s.charAt(i), i);
}
if(!rightMap.keySet().contains(s.charAt(j))){
rightMap.put(s.charAt(j), j);
}
}
ArrayList<Integer> list = new ArrayList<Integer>();
int left,right;
HashSet<Character> set = new HashSet<>();
char ch;
for(int i=0; i<len; ){
ch = s.charAt(i);
if(!set.contains(ch)){
set.add(ch);
left = leftMap.get(ch);
right = rightMap.get(ch);
if(left == right){
list.add(1);
}else{
for(int j=left+1; j<right; j++){
ch = s.charAt(j);
if(!set.contains(ch)){
set.add(ch);
right = Math.max(right, rightMap.get(ch));
}
}
list.add(right-left+1);
}
i = right+1;
}else{
i++;
}
}
return list;
}
}