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();
*/