题目描述:
一个数组中只有两种字符’G’和’B’,
可以让所有的G都放在左侧,所有的B都放在右侧
或者可以让所有的G都放在右侧,所有的B都放在左侧
但是只能在相邻字符之间进行交换操作,请问请问至少需要交换几次,
普通解,看到题目中讲到“只能两两交换”可能会想到冒泡排序,但是时间复杂度过高N^2
最优解:时间复杂度O(N)
小小贪心+双指针:
eg:
BBGGBBGBG
从左向右第一个出现的G一定放在排序后的第1的位置,
从左向右第二个出现的G一定放在排序后的第2的位置,
从左向右第三个出现的G一定放在排序后的第3的位置,
后面的G没必要放在前面G的前面。
最后G全部调到左边之后,B就一定在右侧了,不用管B了。
同上将B放在左边G放在右边。
public class Code04_MinSwapStep {public static int minSteps1(String s) {if (s == null || s.equals("")) {return 0;}char[] str = s.toCharArray();// G在左侧int step1 = 0;int gi = 0;for (int i = 0; i < str.length; i++) {if (str[i] == 'G') {step1 += i - (gi++);}}// B在左侧int step2 = 0;int bi = 0;for (int i = 0; i < str.length; i++) {if (str[i] == 'B') {step2 += i - (bi++);}}return Math.min(step1, step2);}// 可以让G在左,或者在右public static int minSteps2(String s) {if (s == null || s.equals("")) {return 0;}char[] str = s.toCharArray();int step1 = 0;int step2 = 0;int gi = 0;int bi = 0;for (int i = 0; i < str.length; i++) {if (str[i] == 'G') { // 当前的G,去左边 方案1step1 += i - (gi++);} else {// 当前的B,去左边 方案2step2 += i - (bi++);}}return Math.min(step1, step2);}// 为了测试public static String randomString(int maxLen) {char[] str = new char[(int) (Math.random() * maxLen)];for (int i = 0; i < str.length; i++) {str[i] = Math.random() < 0.5 ? 'G' : 'B';}return String.valueOf(str);}public static void main(String[] args) {int maxLen = 100;int testTime = 1000000;System.out.println("测试开始");for (int i = 0; i < testTime; i++) {String str = randomString(maxLen);int ans1 = minSteps1(str);int ans2 = minSteps2(str);if (ans1 != ans2) {System.out.println("Oops!");}}System.out.println("测试结束");}}
