第一题:维护x的秩
题目:
现在我们要读入一串数,同时要求在读入每个数的时候算出它的秩,即在当前数组中小于等于它的数的个数(不包括它自身),请设计一个高效的数据结构和算法来实现这个功能。
给定一个int数组A,同时给定它的大小n,请返回一个int数组,元素为每次加入的数的秩。保证数组大小小于等于5000。
测试样例:
[1,2,3,4,5,6,7],7
返回:
[0,1,2,3,4,5,6]
解析:
比较low,遍历所有
class Rank {
public:
vector<int> getRankOfNumber(vector<int> A, int n) {
// write code here
vector<int> res(n);
res[0] = 0;
for (int i = 1; i < n; ++i) {
res[i] = 0;
for (int j = 0; j < i; ++j) {
if (A[i] >= A[j])
++res[i];
}
}
return res;
}
};
第二题:数组中的逆序对
题目:
有一组数,对于其中任意两个数组,若前面一个大于后面一个数字,则这两个数字组成一个逆序对。请设计一个高效的算法,计算给定数组中的逆序对个数。
给定一个int数组A和它的大小n,请返回A中的逆序对个数。保证n小于等于5000。
测试样例:
[1,2,3,4,5,6,7,0],8
返回:
7
解析:
逆序对问题,详解
class AntiOrder {
public:
int count(vector<int> A, int n) {
// write code here
int res = 0;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (A[i] < A[j]) ++res;
}
}
return res;
}
};
第三题:无缓存交换
题目:
请编写一个函数,函数内不使用任何临时变量,直接交换两个数的值。
给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回交换后的数组。
测试样例:
[1,2]
返回:
[2,1]
解析:
解析一:记住,一时间是想不到的
class Exchange {
public:
vector<int> exchangeAB(vector<int> AB) {
// write code here
AB[0] = AB[0]^AB[1];
AB[1] = AB[0]^AB[1];
AB[0] = AB[0]^AB[1];
return AB;
}
};
解析二: 用加法来解决不用临时变量就能交换的问题。
例如:
a = 1; b = 2;
a = a + b = 3;
b = a(3) - b (2)= a (1)+ b (2)- b(2) = 1;
a = a(3) - b(1) = a(1) + b(2) - ( a(1) + b(2) - b(2) ) = 2;
括号里的数字代表的数当前字母的值
class Exchange {
public:
vector<int> exchangeAB(vector<int> AB) {
// write code here
AB[1] = AB[0] + AB[1];
AB[0] = AB[1] - AB[0]; //AB[1]
AB[1] = AB[1] - AB[0];
return AB;
}
};
第四题:井字棋
题目:
对于一个给定的井字棋棋盘,请设计一个高效算法判断当前玩家是否获胜。
给定一个二维数组board,代表当前棋盘,其中元素为1的代表是当前玩家的棋子,为0表示没有棋子,为-1代表是对方玩家的棋子。
测试样例:
[[1,0,1],[1,-1,-1],[1,-1,0]]
返回:
true
解析:
解析一:检测所有获胜的条件
class Board {
public:
bool checkWon(vector<vector<int> > board) {
// write code here
if (board[0][0] == 1) {
if (board[0][1] == 1 && board[0][2] == 1) return true;
if (board[1][0] == 1 && board[2][0] == 1) return true;
}
if (board[2][2] == 1) {
if (board[2][0] == 1 && board[2][1] == 1) return true;
if (board[0][2] == 1 && board[1][2] == 1) return true;
}
if (board[1][1] == 1) {
if (board[1][0] == 1 && board[1][2] == 1) return true;
if (board[0][1] == 1 && board[2][1] == 1) return true;
if (board[0][0] == 1 && board[2][2] == 1) return true;
if (board[0][2] == 1 && board[2][0] == 1) return true;
}
return false;
}
};
解析二:3竖3横两条斜线
class Board {
public:
bool checkWon(vector<vector<int> > board) {
// write code here
if (board[0][0] + board[1][1] + board[2][2] == 3) return true;
if (board[0][2] + board[1][1] + board[2][0] == 3) return true;
for (int i = 0; i < 3; i++) {
if (board[i][0] + board[i][1] + board[i][2] == 3) return true;
if (board[0][i] + board[1][i] + board[2][i] == 3) return true;
}
return false;
}
};
第五题:无判断max
题目:
请编写一个方法,找出两个数字中最大的那个。条件是不得使用if-else等比较和判断运算符。
给定两个int a和b,请返回较大的一个数。若两数相同则返回任意一个。
测试样例:
1,2
返回:
2
解析:
a和b的差的绝对值是abs(a - b),然后差的绝对值加上a和b的和即为最大值的两倍。
同理求两数较小的一个,a + b - abs(a - b)即可。
class Max {
public:
int getMax(int a, int b) {
// write code here
return (a + b + abs(a - b)) / 2;
}
};
第六题:珠玑妙算
题目:
我们现在有四个槽,每个槽放一个球,颜色可能是红色®、黄色(Y)、绿色(G)或蓝色(B)。例如,可能的情况为RGGB(槽1为红色,槽2、3为绿色,槽4为蓝色),作为玩家,你需要试图猜出颜色的组合。比如,你可能猜YRGB。要是你猜对了某个槽的颜色,则算一次“猜中”。要是只是猜对了颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。
给定两个string A和guess。分别表示颜色组合,和一个猜测。请返回一个int数组,第一个元素为猜中的次数,第二个元素为伪猜中的次数。
测试样例:
“RGBY”,“GGRR”
返回:
[1,1]
解析:
class Result {
public:
vector<int> calcResult(string A, string guess) {
// write code here
vector<int> res(2, 0);
int count = 0;
int r1 = 0, y1 = 0, g1 = 0, b1 = 0;
int r2 = 0, y2 = 0, g2 = 0, b2 = 0;
for (int i = 0; i < A.size(); ++i) {
if (A[i] == guess[i]) ++count;
if (A[i] == 'R') {
++r1;
}
else if (A[i] == 'Y') {
++y1;
}
else if (A[i] == 'G') {
++g1;
}
else if (A[i] == 'B') {
++b1;
}
if (guess[i] == 'R') {
++r2;
}
else if (guess[i] == 'Y') {
++y2;
}
else if (guess[i] == 'G') {
++g2;
}
else if (guess[i] == 'B') {
++b2;
}
}
int sum = 0;
sum += r1 < r2 ? r1 : r2;
sum += y1 < y2 ? y1 : y2;
sum += g1 < g2 ? g1 : g2;
sum += b1 < b2 ? b1 : b2;
res[0] = count;
res[1] = sum - count;
return res;
}
};
第七题:阶乘尾零
题目:
请设计一个算法,计算n的阶乘有多少个尾随零。
给定一个int n,请返回n的阶乘的尾零个数。保证n为正整数。
测试样例:
5
返回:
1
解析:
计算阶乘中因子为5的个数
class Factor {
public:
int getFactorSuffixZero(int n) {
// write code here
int sum = 0;
while (n) {
n /= 5;
sum += n;
}
return sum;
}
};