网易面试题——调整队形
分类:Interview
题目:
在幼儿园有n个小朋友排列为一个队伍,从左到右一个挨着一个编号为(0~n-1)。其中有一些是男生,有一些是女生,男生用’B’表示,女生用’G’表示。小朋友们都很顽皮,当一个男生挨着的是女生的时候就会发生矛盾。作为幼儿园的老师,你需要让男生挨着女生或者女生挨着男生的情况最少。你只能在原队形上进行调整,每次调整只能让相邻的两个小朋友交换位置,现在需要尽快完成队伍调整,你需要计算出最少需要调整多少次可以让上述情况最少。例如:
GGBBG -> GGBGB -> GGGBB
这样就使之前的两处男女相邻变为一处相邻,需要调整队形2次
输入描述:
输入数据包括一个长度为n且只包含G和B的字符串.n不超过50.
输出描述:
输出一个整数,表示最少需要的调整队伍的次数
输入例子:
GGBBG
输出例子:
2
分析:
解:最后矛盾最少的状态只可能是男生和女生分别在两边,最多只有中间一个男生挨着女生,所以总共有两种方式:男生全部在座女生全部在右;女生全部在坐男生全部在右。
算法:所以分两种情况:把男生全部移到左边;把女生全部移到左边。再从两个数中求一个最小值即可。在移动的时候可以用一个游标记录一次需要移动的位置次数,这样会简化移动过程,不需要每次只能移动一步。
算法代码:
int adjustFormation(const char * formation, int size) { bool * formBoyMove = new bool[size]; bool * formGirlMove = new bool[size]; for (int i = 0; i < size; ++i) { if ('B' == formation[i]) { formBoyMove[i] = formGirlMove[i] = true; } else { formBoyMove[i] = formGirlMove[i] = false; } } int minChangeTimes, boyMove, girlMove; boyMove = girlMove = 0; int tempChangingTimes = 1; //move boy for (int i = 0; i < size; ++i) { if (true == formBoyMove[i]) { continue; } else { //find the closest boy while (true != formBoyMove[i+tempChangingTimes] && (tempChangingTimes + i) < size) { ++tempChangingTimes; } //no boys behind if (tempChangingTimes + i >= size) { //move end break; } //change formation for tempChangingTimes formBoyMove[i] = true; formBoyMove[i+tempChangingTimes] = false; boyMove += tempChangingTimes; //reset tempChangingTimes tempChangingTimes = 1; } } //reset tempChangingTimes tempChangingTimes = 1; //move girl for (int i = 0; i < size; ++i) { if (false == formGirlMove[i]) { continue; } else { //find the closest girl while (false != formGirlMove[i+tempChangingTimes] && (tempChangingTimes + i) < size) { ++tempChangingTimes; } //no girls behind if (tempChangingTimes + i >= size) { //move end break; } //change formation for tempChangingTimes formGirlMove[i] = false; formGirlMove[i+tempChangingTimes] = true; girlMove += tempChangingTimes; //reset tempChangingTimes tempChangingTimes = 1; } } minChangeTimes = min(boyMove, girlMove); return minChangeTimes; }
测试代码:
// // main.cpp // adjustFormation // // Created by Jiajie Zhuo on 2017/4/7. // Copyright © 2017年 Jiajie Zhuo. All rights reserved. // #include <iostream> #define MAXNUMBER 50 using namespace std; int adjustFormation(const char * formation, int size); int main(int argc, const char * argv[]) { cout << "Please enter the formation of students: "; char * formation = new char[MAXNUMBER]; cin >> formation; int size = (int)strlen(formation); int minChangeTimes = adjustFormation(formation, size); cout << "The minimum times of changing is " << minChangeTimes << endl; delete [] formation; return 0; }
总结:
简化问题的关键点即是用一个游标记录下一个男生(女生)的的位置,这样可以一次移动多步。
如果有收获,可以请我喝杯咖啡!