难度:
Hard
题意:
思路:
解法一:
class Solution {
private class Item implements Comparable<Item> {
int alph;
int idx;
int pos;
public Item(int alph, int idx, int pos) {
this.alph = alph;
this.idx = idx;
this.pos = pos;
}
@Override
public int compareTo(Item o) {
return Integer.compare(pos, o.pos);
}
}
private int solve(List[] idxList, int start, int len, int[] init) {
PriorityQueue<Item> queue = new PriorityQueue<Item>();
boolean[] flag = new boolean[26];
for (int i = 0;i < 26;i++) {
flag[i] = false;
}
int ret = 0;
int res = 0;
int pre = start - 1;
for (int i = 0;i < 26;i++) {
int idx = init[i];
if (idx != idxList[i].size()) {
queue.add(new Item(i, idx, (Integer) idxList[i].get(idx)));
}
}
while (!queue.isEmpty()) {
Item top = queue.poll();
ret += (long) res * (top.pos - pre) % MOD;
if (ret >= MOD) {
ret -= MOD;
}
if (flag[top.alph]) {
res--;
} else {
flag[top.alph] = true;
if (top.idx + 1 != idxList[top.alph].size()) {
queue.add(new Item(top.alph, top.idx + 1, (Integer) idxList[top.alph].get(top.idx + 1)));
}
res++;
}
pre = top.pos;
}
ret += (long) res * (len - pre) % MOD;
if (ret >= MOD) {
ret -= MOD;
}
return ret;
}
private static int MOD = 1000000007;
public int uniqueLetterString(String S) {
List[] idxList = new List[26];
int[] init = new int[26];
for (int i = 0;i < 26;i++) {
idxList[i] = new ArrayList<Integer>();
init[i] = 0;
}
for (int i = 0;i < S.length();i++) {
idxList[S.charAt(i) - 'A'].add(i);
}
int ret = 0;
for (int i = 0;i < S.length();i++) {
ret += solve(idxList, i, S.length(), init);
if (ret >= MOD) {
ret -= MOD;
}
init[S.charAt(i) - 'A']++;
}
return ret;
}
}
解法二:
class Solution {
private static int MOD = 1000000007;
public int uniqueLetterString(String S) {
List<Integer>[] idxList = new List[26];
int[] pos = new int[26];
for (int i = 0;i < 26;i++) {
idxList[i] = new ArrayList<Integer>();
pos[i] = 0;
}
for (int i = 0;i < S.length();i++) {
idxList[S.charAt(i) - 'A'].add(i);
}
int ret = 0;
int res = 0;
for (int i = 0;i < 26;i++) {
if (pos[i] < idxList[i].size()) {
if (pos[i] + 1 < idxList[i].size()) {
res += idxList[i].get(pos[i] + 1) - idxList[i].get(pos[i]);
} else {
res += S.length() - idxList[i].get(pos[i]);
}
}
}
for (int i = 0;i < S.length();i++) {
ret += res;
if (ret >= MOD) {
ret -= MOD;
}
int j = S.charAt(i) - 'A';
if (pos[j] + 1 < idxList[j].size()) {
res -= idxList[j].get(pos[j] + 1) - idxList[j].get(pos[j]);
} else {
res -= S.length() - idxList[j].get(pos[j]);
}
pos[j]++;
if (pos[j] < idxList[j].size()) {
if (pos[j] + 1 < idxList[j].size()) {
res += idxList[j].get(pos[j] + 1) - idxList[j].get(pos[j]);
} else {
res += S.length() - idxList[j].get(pos[j]);
}
}
}
return ret;
}
}