一、前言
如果一直有看我的每周面試題的童鞋們,應該都知道,之前的面試題中很少或者說基本沒有程序題,可是開發崗位的面試是無法避免程序題的,因此這周來一提程序題。
二、題目
在幼兒園有 n 個小朋友排列為一個隊伍,從左到右一個挨著一個編號為 ( 0 ~ n-1 ) 。其中有一些是男生,有一些是女生,男生用 ’B’ 表示,女生用 ’G’ 表示。小朋友們都很頑皮,當一個男生挨著的是女生的時候就會發生矛盾。作為幼兒園的老師,你需要讓男生挨著女生或者女生挨著男生的情況最少。你只能在原隊形上進行調整,每次調整只能讓相鄰的兩個小朋友交換位置,現在需要盡快完成隊伍調整,你需要計算出最少需要調整多少次可以讓上述情況最少。例如:
GGBBG -GGBGB -GGGBB
這樣就使之前的兩處男女相鄰變為一處相鄰,需要調整隊形 2 次
輸入描述:
輸入數據包括一個長度為 n 且只包含 G 和 B 的字符串. n 不超過 50.
輸出描述:
輸出一個整數,表示最少需要的調整隊伍的次數
輸入例子:
GGBBG
輸出例子:
2
三、解題
題目的意思應該很好就能理解,不能理解的看下給出的例子,基本就能知道題目表達的意思了。根據題目的意思,“男生挨著女生或者女生挨著男生的情況最少”,那么最終調整的隊形無非就兩個結果,第一:男生全部在左,女生全部在隊列的右邊,中間只有一男一女是相挨著的。第二:要么就是反過來,女生全部在左,男生在右。也就是假設長度為 8 的時候,只要調整為 BBBBGGGG 或者 GGGGBBBB 就行了。
這是根據第一個條件進行分析的結果,那么我們看第二個條件,“每次調整只能讓相鄰的兩個小朋友交換位置,且需要的是最少需要調整的情況” , 從上面可以知道,我們最終需要將隊形調整成 BBBBGGGG 或者 GGGGBBBB 就可以了,那么調整的時候我們只需要調整 B 或者 G 就可以了,意思就是說調整 B 的時候,G 不動,如果調整 G ,B 不動。為什么呢?因為只動 B 和只動 G 是等價的。
用 JAVA 來編程的話,我們就只移動 B ,用一個 list 記錄每個 B 所在的位置(從 0 開始),比如 GGBBG , list 中有兩個值, 2 和 3 ,大小為 2 ,如果序列為 2 的 B 移動到最左邊需要移動的次數是 2 次,也就變成 BGGBG,序列為 3 的 B 移動到最左邊需要移動的次數是 3 次,可是因為之前已經移動號了一個,我們只需移動 2 次就行了,也就是移動到第一次移動到最左邊的 B 的左邊;所以我們可以對當前每個 B 的下標求和,每進行一次有用的調整必然使當前的和 +1 或者 -1,最后我們只要計算出當前的和與最終結果的和的差。
public class AdjustFormation {
public static void main(String[] args) {
// 控制臺輸入
Scanner sc = new Scanner(System.in);
String s = sc.next();
sc.close();
int n = s.length();
if (n <= 0 || n > 50) {
throw new RuntimeException("the length is too long");
}
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (s.charAt(i) == 'B') {
list.add(i);
}
}
int bSize = list.size();
int indexSum = 0;
for (int val : list) {
indexSum += val;
}
int left = indexSum - bSize * (bSize - 1) / 2;
int right = bSize * (n - 1) - indexSum - bSize * (bSize - 1) / 2;
// 移左 或者 移右 ,選擇最少的
System.out.println(Math.min(left, right));
}
}
運行的結果: