题目:
假设一个数组中只有两种字符’G’和’B’,可以让所有的G都放在左侧,所有的B都放在右侧;或者让所有的B都在左侧,所有的G都在右侧,但是只能在相邻字符之间进行交换操作,请问至少要交换多少次
解题思路
提示:注意题目里面有一个迷惑的点,就是分两种情况,分别是G在左或者B在左的情况,一般情况下两种情况得到的结果是不同的,而这里需要比较两种情况的结果,取最少的次数。
- 暴力解法
使用冒泡排序实现,时间复杂度是O(n^2) - 指针滑动
由于在数组中只有’G’,‘B’两种字符,所以没必要使用冒泡,因为相同字符之间是"无序"的,即最后的结果只需要实现一种字符在左边,另一种字符在右边即可,至于相同字符之间哪个在前面哪个在后面是无意义的。所以假设找到第一个字符’G’(假设代表G索引位置的变量为index),那么就把这个G放到索引(假设使用变量L来表示)为0的位置,找到第二个’G’后放在索引为1的位置,往后依次把L加1即可,那么每次找到’G’并交换到L所在位置的次数为:index - L,最后遍历完整个数组后即可得到总次数,此时时间复杂度为O(n)
代码实现:
static void sort(char[] chars) {
// 每一个字符'G'交换的索引,第一个G放在最左,此后依次加1
int G = 0;
// 第二种字符'B'全在左侧的情况,操作和G一样
int B = 0;
int step = 0;
int step2 = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 'G') {
step += i - (G++);
} else {
step2 += i - (B++);
}
}
System.out.println(Math.min(step, step2));
}