2016小米在线编程题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NK_test/article/details/52882231

题目一


世界上有10种人,一种懂二进制,一种不懂。那么你知道两个int32整数m和n的二进制表达,有多少个位(bit)不同么?
思路:很简单啊,异或操作,然后右移算出1的个数。

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;
    }
};

猜你喜欢

转载自blog.csdn.net/NK_test/article/details/52882231