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
所以,只需要投两次硬币,如果两次的结果相同那么重新开始;两次的结果不同的话就可以了判断了