题目一
class Solution {
public:
/**
* 获得两个整形二进制表达位数不同的数量
*
* @param m 整数m
* @param n 整数n
* @return 整型
*/
int countBitDiff(int m, int n) {
int ans = m ^ n;
int res = 0;
while (ans) {
if (ans & 1) {
res ++;
}
ans = ans >> 1;
}
return res;
}
};
题目二:
风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。 设计算法,计算你能获得的最大收益。 输入数值范围:2<=n<=100,0<=prices[i]<=100
输入: 3,8,5,1,7,8 输出:12
思路:虽然多阶段和最大这种问题应该用动态规划求解,但这个状态方程不太好找,并且最多只可以买2次,我们可以尝试使用对称操作。
从左向右扫一遍,记录a[0]~a[i]位置的最大收益;从右向左扫一遍,记录a[i]~a[n]的最大收益;然后遍历分割点取最大值即可。
class Solution {
public:
/**
* 计算你能获得的最大收益
*
* @param prices Prices[i]即第i天的股价
* @return 整型
*/
int calculateMax(vector<int> prices) {
int nMax = 0;
vector<int> left, right;
for (int i = 0; i < prices.size() - 1; i++) {
for (int j = i + 1; j < prices.size(); j++) {
nMax = max(nMax, prices[j] - prices[i]);
}
}
int lMin = prices[0];
int maxPro;
maxPro = 0;
left.push_back(0);
for (int i = 1; i < prices.size(); i++) {
if (prices[i] < lMin) {
lMin = prices[i];
}
maxPro = max(maxPro, prices[i] - lMin);
left.push_back(maxPro);
}
int rMax = prices[prices.size() - 1];
maxPro = 0;
right.push_back(0);
for (int i = prices.size() - 2; i >= 0; i--) {
if (prices[i] > rMax)
rMax = prices[i];
maxPro = max(maxPro, rMax - prices[i]);
right.push_back(maxPro);
}
reverse(right.begin(), right.end());
for (int i = 0;i < prices.size(); i++) {
nMax = max(nMax, left[i] + right[i]);
}
return nMax;
}
};
题目三:
git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0'或'1'组成,长度为n。matrix[i][j]=='1'当且仅当git树种第i个和第j个节点有连接。节点0为git树的根节点。)
输入:[01011,10100,01000,10000,10000],1,2 输出: 1
思路:看上去题目不太好理解,其实就是给你一个邻接矩阵和一个树,让你求给定的两个结点之间的最近祖先。值的注意的是 直接根据矩阵不好判断父子结点的关系,需要预先处理一下,然后就可以分别向上递归记录路径,用vis数组标记,找到第一个重复的结点即可。当然你也可以使用LCA算法。
class Solution {
public:
/**
* 返回git树上两点的最近分割点
*
* @param matrix 接邻矩阵,表示git树,matrix[i][j] == '1' 当且仅当git树中第i个和第j个节点有连接,节点0为git树的跟节点
* @param indexA 节点A的index
* @param indexB 节点B的index
* @return 整型
*/
void setDirected(vector<string> &matrix ,int r) {
for(int j = 0 ;j < matrix.size(); j++) {
if(matrix[r][j] == '1' ) {
matrix[j][r] = '0';
setDirected(matrix,j);
}
}
}
int getSplitNode(vector<string> matrix, int indexA, int indexB) {
int n = matrix.size();
setDirected(matrix, 0);
int fath[1000],vis[1000];
memset(fath, -1, sizeof(fath));
memset(vis, -1, sizeof(vis));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '1')
fath[j] = i;
}
}
vis[indexA] = 1;
int father;
father = fath[indexA];
while (father != -1) {
vis[father] = 1;
father = fath[father];
}
if (vis[indexB] == 1)
return indexB;
int res = 0;
father = fath[indexB];
while(father != -1) {
if (vis[father] == 1) {
res = father;
break;
}
father = fath[father];
}
return res;
}
};