今日头条的面试题(部分)

1.给定一个有序数组,输出平方后消重结果中数字的个数,每次删除一个最大的数

比如: -2, -2, -1,0,1消重后有3个数;

0,0,1,2,3,4,5,5,6消重后有7个数

O(n)复杂度解法:

int count(vector<int>& nums)
{
    int len = nums.size();
    if (len < 2)
        return len;
    int count = 0;
    int i = 0;
    int j = len - 1;
    //上一个被删除的数字,为了保证第一个数能够正常删除,所以用了一个比INT_MAX还大的数
    unsigned int prev = (unsigned int)INT_MAX + 1;
    //左边指针指向数字的绝对值
    //这里必须是unsigned int ,因为INT_MIN的绝对值比INT_MAX要大
    unsigned int left = 0;
    //右边指针指向数字的绝对值
    unsigned int righ = 0;
    while (i <= j)
    {
        left = abs(nums[i]);
        right = abs(nums[j]);
        //每次删除较大或相等的数,并且要保证这个数没有被删除过
        if (left > right)
        {
            if (left != prev)
            {
                prev = left;
                count++;        
            }    
        }
        else
        {        
            if (right != prev)
            {
                prev = right;
                count++;        
            }   
        }
    }
    return count;
}

2.多个链表归并,注意priority_queue的用法以及运算符重载

leetcode23

https://leetcode.com/problems/merge-k-sorted-lists/

class CMP {
public:
    bool operator()(const ListNode* lhs, const ListNode* rhs) {
        return lhs->val > rhs->val;
    }
};
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {

        //注意运算符的重载以及priority_queue的写法
        priority_queue<ListNode*, vector<ListNode*>, CMP> Q; 

        for (auto head: lists)
        {
            if (head) Q.push(head);
        }
        ListNode* newhead = NULL;
        ListNode* cur = NULL;
        while (!Q.empty())
        {
            ListNode* tmp = Q.top();
            Q.pop(); 
            if (!newhead)
            {
                newhead = new ListNode(tmp->val);
                cur = newhead;
            }
            else
            {
                cur->next = new ListNode(tmp->val);
                cur = cur->next;
            }
            tmp = tmp->next;
            if (tmp)
                Q.push(tmp);
        }
        return newhead;
    }
};

3.combination sum的优化,主要优化在于t <= candidates[st]的时候就可以退出了

leetcode40

https://leetcode.com/problems/combination-sum-ii/

class Solution {
public:
    void getsum(vector<int>& tmp, vector<int>& candidates, vector<vector<int>>& res, int t, int st)
    {
        if (t == 0)
        {
            res.push_back(tmp);
            return ;
        }
        if (st >= candidates.size())
            return ;
        for (int i = st; i < candidates.size(); i++)
        {
            if (t < candidates[i])
                return;
            tmp.push_back(candidates[i]);
            getsum(tmp, candidates, res, t-candidates[i], i+1);
            tmp.pop_back();
            if (t == candidates[i])
                return;
            while (i+1 < candidates.size() && candidates[i] == candidates[i+1])
                i++;
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        int len = candidates.size();
        vector<vector<int>> res;
        if (len == 0)
            return res;
        sort(candidates.begin(), candidates.end());
        vector<int> tmp;
        getsum(tmp, candidates, res, target, 0);
        return res;
    }
};

4.股票问题,这个用状态机的话就很简单了

5.验证出栈顺序,leetcode946

新建一个栈,直接入栈到能出栈即可验证

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> S;
        int len = pushed.size();
        int pindex = 0;
        for (int num: popped)
        {
            while (pindex < len && (S.empty() || S.top() != num))
            {
                S.push(pushed[pindex++]);
            }
            if (S.top() == num)
                S.pop();
        }
        return S.empty();
    }
};

6.堆排序 (略)

7.利用不均匀硬币产生等概率

假设正面的概率为p,反面的概率为1-p

投两次硬币,

两次都朝上: p*p

两次都朝下:(1-p)*(1-p)

第一次正第二次反:p*(1-p)

第一次反第二次正:(1-p)*p

所以,只需要投两次硬币,如果两次的结果相同那么重新开始;两次的结果不同的话就可以了判断了

发布了48 篇原创文章 · 获赞 4 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/m0_37313888/article/details/88233596
今日推荐