1234平衡までバランスのとれた文字列のサブストリングの置換文字列のサブストリングを交換してください
問題の説明
だけ含む'Q', 'W', 'E', 'R'
4文字の種類、およびの長さn
の文字列を。
この文字列は、これらの4つの文字が正確に表示された場合はn/4
、一度、それは「バランスの取れた文字列」です。
あなたにこのような文字列を付けs
て下さい、アプローチ「サブ置き換える」を、元の文字列となるようs
に、「バランスの取れた文字列です。」
あなたは、同じ長さ「によって交換するサブストリング」と使用することができます任意の交換を完了するために他の文字列。
交換する部分文字列の可能な最小の長さに戻ってください。
元の文字列そのものである場合はバランスの取れた文字列が返されます0
。
例1:
入力: S = "QWER"
出力: 0
説明: Sはすでにバランスです。
例2:
入力: S = "QQWE"
出力: 1つの
説明:私たちは、 'Q' 'R'に置き換え、このようにして得られた"RQWE"を必要とする(または"QRWE")がバランスしています。
例3:
入力: S =「QQQW」
出力: 2
説明:私たちは、「QQ」の前に置くことができる「ER」に置き換えます。
例4:
入力: S = "QQQQ"
出力: 3
説明:私たちは3 'Q'に置き換えることができますので、S = "QWER"。
ヒント:
1 <= s.length <= 10^5
s.length
それは4
、複数の
s
それだけ含まれている'Q'
、'W'
、'E'
、'R'
4つの文字クラスを
考え
- タイトル読む
平衡文字列を:4つの文字で置き換えることによって、同じ数を表示されたサブストリングのバランス任意の文字列で取得した
ゲームポイントの追加ウォッシュ(ボディ力感度の高い方法を)演奏のように多少の、平均より高いが、平均以下に低減され、その後、割り当てられた点の数で得られた還元
スライディングウィンドウ(ダブルポインタ)
出発点として前で、次へ前への条件まで、移動しようと、後方に移動
- 満たす条件は、ストリングの長さを減少させた前のページに移動し続けます
- 次は移動し続ける満たしていません
- サンプル: "WQWQQRQE"
コードの実装
スライディングウィンドウ
class Solution {
public int balancedString(String s) {
int len = s.length(), chrSize = 4;
// 字符数量不足4个 或 不是4的倍数
if (len < chrSize || len % chrSize != 0) {
return -1;
}
int balanced = len / 4;
char[] chrs = s.toCharArray();
int[] cnt = new int[chrSize];
for (char chr : chrs) {
cnt[c2i(chr)]++;
}
// 如果已经是一个平衡字符串 不用修改
if (check(cnt, balanced)) {
return 0;
}
// 使用滑动窗口 [prev, next) 左闭右开
int ans = Integer.MAX_VALUE, prev = 0, next = 0;
while (next >= prev) {
if (check(cnt, balanced)) {
ans = Math.min(ans, next - prev);
cnt[c2i(chrs[prev])]++;
prev++;
} else {
if (next >= len) {
break;
}
cnt[c2i(chrs[next])]--;
next++;
}
System.out.printf("ans:%d [prev:%d, next:%d] cnt:%s balanced:%d\n", ans, prev, next, Arrays.toString(cnt), balanced);
System.out.println(s.substring(0, prev) + "][" + s.substring(next, len) + " --> [" + s.substring(prev, next) + "]");
}
return ans;
}
private boolean check(int[] cnt, int balanced) {
return cnt[c2i('Q')] <= balanced &&
cnt[c2i('W')] <= balanced &&
cnt[c2i('E')] <= balanced &&
cnt[c2i('R')] <= balanced;
}
/**
* 字符映射为数字
* @param chr 被映射字符
* @return 映射字符定义的数字
*/
private int c2i(char chr) {
// Q:0 W:1 E:2 R:3
if (chr == 'Q') {
return 0;
} else if (chr == 'W') {
return 1;
} else if (chr == 'E') {
return 2;
} else if (chr == 'R') {
return 3;
} else {
return -1;
}
}
}