leetcode刷题记录---19.11.16 两整数之和位运算,递增的三元子序列3个坑位,(微软面试题)数据流中位数vector.insert.lower_bound(优先级队列,堆)

1.两整数之和

题目描述:

不使用运算符 + 和 - ,计算两整数 a 、b 之和。

示例 1:

输入: a = 1, b = 2
输出: 3
示例 2:

输入: a = -2, b = 3
输出: 1

class Solution {
public:
    int getSum(int a, int b) {
        while(b){
            int carry = ((unsigned int)(a&b))<<1;
            a = a^b;
            b = carry;
        }
        return a;
    }
};

2.递增的三元子序列

题目描述:

给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。

数学表达式如下:

如果存在这样的 i, j, k,  且满足 0 ≤ i < j < k ≤ n-1,
使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。

示例 1:

输入: [1,2,3,4,5]
输出: true
示例 2:

输入: [5,4,3,2,1]
输出: false

思路:

总共就3个坑位,满足a<b<c,只需要将合适的元素填入坑位就好。

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int one = INT_MAX;
        int two = INT_MAX;
        for(auto i:nums){
            if(i<=one) one = i;
            else if(i<=two) two = i;
            else return true;
        }
        return false;
    }
};

3.数据流的中位数(hard)

题目描述:

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例:

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3) 
findMedian() -> 2

解法:

插入排序

vector的insert(iter,3,1)函数:在iter位置插入3个1

lower_bound():针对有序数组,返回值是一个迭代器,返回指向大于等于key的第一个值得位置,需包含的头文件是algorithm。

class MedianFinder {
public:
    /** initialize your data structure here. */
    vector<int> nums;
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        if(nums.empty()) nums.push_back(num);
        else nums.insert(lower_bound(nums.begin(),nums.end(),num),num);
    }
    
    double findMedian() {
        int n = nums.size();
        return n&1 ? nums[n/2]:(nums[n/2]+nums[n/2-1])*0.5;
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

2个堆解决:

1.用于存储输入数字中较小一半的最大堆

2.用于存储输入数字中较大一半的最小堆

巨大难题:如何平衡这两个堆?

1.两个优先级队列:

           1.用于存储较小一半数字的最大堆lo

           2.用于存储较大一半数字的最小堆hi

2.最大堆lo允许存储的元素最多比最小堆hi多一个。因此我们处理k元素:

            1.如果k = 2*n+1,那就允许lo持有n+1元素,而hi可以持有n元素

            2.如果k = 2* n,两个堆都是平衡的,并且包含的元素个数相同

class MedianFinder {
public:
    /** initialize your data structure here. */
    priority_queue<int> lo;
    priority_queue<int,vector<int>,greater<int>> hi;
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        lo.push(num);
        hi.push(lo.top());
        lo.pop();
        if(lo.size()<hi.size()){
            lo.push(hi.top());
            hi.pop();
        }
    }
    
    double findMedian() { 
        return lo.size()>hi.size() ? (double)lo.top():(lo.top()+hi.top())*0.5;
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值