Se da una cadena S
de letras minúsculas. Queremos dividir esta cadena en tantas partes como sea posible para que cada letra aparezca como máximo en una parte y devolver una lista de enteros que represente el tamaño de estas partes.
Ejemplo 1:
Entrada: S = "ababcbacadefegdehijhklij" Salida: [9,7,8] Explicación: La partición es "ababcbaca", "defegde", "hijhklij". Esta es una partición para que cada letra aparezca como máximo en una parte. Una partición como "ababcbacadefegde", "hijhklij" es incorrecta, ya que divide S en menos partes.
Idea: Escanee dos veces, registre la última posición de cada char en la primera pasada y la segunda vez, vea si la última posición de char es mayor que maxend y actualice si es más grande, de lo contrario si i == maxend indica que desde el inicio hasta maxend Una cadena válida, luego start = i + 1 y así sucesivamente;
Principalmente es más difícil grabar el último carácter, y luego es más difícil actualizar el último maxend, el resto es la idea de dos punteros;
class Solution {
public List<Integer> partitionLabels(String S) {
List<Integer> list = new ArrayList<Integer>();
if(S == null || S.length() == 0) {
return list;
}
HashMap<Character, Integer> hashmap = new HashMap<>();
for(int i = 0; i < S.length(); i++) {
char c = S.charAt(i);
// store last position of this char;
hashmap.put(c, i);
}
int start = 0;
int maxend = 0;
for(int i = 0; i < S.length(); i++) {
char c = S.charAt(i);
if(hashmap.get(c) > maxend) {
maxend = hashmap.get(c);
}
if(i == maxend) {
list.add(maxend - start + 1);
maxend = 0;
start = i + 1;
}
}
return list;
}
}