一、数据流中的中位数

题目

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

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

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

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

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

示例 1:

输入:
["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]
[[],[1],[2],[],[3],[]]
输出:[null,null,null,1.50000,null,2.00000]

示例 2:

输入:
["MedianFinder","addNum","findMedian","addNum","findMedian"]
[[],[2],[],[3],[]]
输出:[null,null,2.00000,null,2.50000]

限制:

  • 最多会对​​addNum、findMedian​​​ 进行​​50000​​ 次调用。

题解

需要用到优先队列的思想,分别记录大于中位数queMax和小于等于中位数queMin的数。

当累计添加的数为奇数时,queMin 中的数的数量比9.21Leetcode记录_Leetcode

9.21Leetcode记录_中位数_02

9.21Leetcode记录_子数组_03

9.21Leetcode记录_Leetcode_04

9.21Leetcode记录_子数组_05

9.21Leetcode记录_子数组_06

9.21Leetcode记录_子数组_07

9.21Leetcode记录_数组_08

代码

class MedianFinder {
public:
/** initialize your data structure here. **/

priority_queue<int, vector<int>, less<int>> queMin;
priority_queue<int, vector<int>, greater<int>> queMax;

MedianFinder() {

}

void addNum(int num) {
if(queMin.empty()||num<=queMin.top())
{
queMin.push(num);
if(queMax.size()+1<queMin.size())
{
queMax.push(queMin.top());
queMin.pop();
}
}
else
{
queMax.push(num);
if(queMin.size()<queMax.size())
{
queMin.push(queMax.top());
queMax.pop();
}
}

}

double findMedian() {
if(queMin.size()>queMax.size())
return double(queMin.top());
else
return (queMin.top()+queMax.top())/2.0;
}
};

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

 二、把数组排成最小的数

题干:

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: "102"

示例 2:

输入: [3,30,34,5,9]
输出: "3033459"

提示:

0 < nums.length <= 100
说明:

输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

题解

对数组进行排序,排序时进行比较,选择两个数加起来较小的一方。

代码

class Solution {
public:
string minNumber(vector<int>& nums) {

vector<string> strs;
for(auto num:nums)
{
strs.push_back(to_string(num));
}
sort(strs.begin(),strs.end(),comp);
string ans;
for(auto str:strs){
ans+=str;
}
return ans;
}

static bool comp(string a,string b)
{
return a+b<b+a;
}


};

三、连续子数组的最大和

题干

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

提示:

  • ​1 <= arr.length <= 10^5​
  • ​-100 <= arr[i] <= 100​

题解

对于数组中的每个数,找出以他为终点的子数组最大和,因此只需将:目前的数+前一个数的子数组最大和>目前的数,则目前的数为加和之后的。

对整个数组遍历一遍,即可求出每个位置上的以他为终点的子数组的最大和。

代码

class Solution {
public:
int maxSubArray(vector<int>& nums) {
int a_max=nums[0];
int maxn=a_max;

for(int i=1;i<nums.size();i++)
{
if(nums[i]+nums[i-1]>nums[i])
{
nums[i]=nums[i]+nums[i-1];
maxn=max(nums[i],maxn);
}
else
{
maxn=max(nums[i],maxn);
}
}
return maxn;

}
};