1.数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
采用大小堆的方法,排序来实现,采用PriorityQueue的数据结构,该数据结构具有自动采用堆排序的队列特点,因此可以将较大的值存于minQueue(小顶堆),较小的值存在于maxQueue(大顶堆),此时小顶堆的最小值大于大顶堆的最大值,奇数中存于小顶堆,偶数时存于大顶堆,取中位数中根据奇数偶数来选择。
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
private PriorityQueue<Integer> minQueue = new PriorityQueue<Integer>();
private PriorityQueue<Integer> maxQueue = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
int count = 1;
public void Insert(Integer num) {
if(count%2==1){
maxQueue.offer(num);
minQueue.offer(maxQueue.poll());
}else{
minQueue.offer(num);
maxQueue.offer(minQueue.poll());
}
count ++;
}
public Double GetMedian() {
if(count%2 == 0){
return new Double(minQueue.peek());
}else{
return new Double(maxQueue.peek()) + new Double(minQueue.peek()-maxQueue.peek())/2;
}
}
}
2.字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
1)采用数组来维护;
字符的总共种类有256种,因此定义大小位256的字符串数组char[] hash;。取第一个不重复字符时候可以根据判断hash数组在s种的第一个为1的字符。
class Solution
{
public:
//Insert one char from stringstream
string s;
char hash[256]={0};
void Insert(char ch)
{
s+=ch;
hash[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
int size=s.size();
for(int i=0;i<size;++i)
{
if(hash[s[i]]==1)
return s[i];
}
return '#';
}
};
2)采用队列来维护
import java.util.Queue;
import java.util.concurrent.LinkedTransferQueue;
public class Solution {
//Insert one char from stringstream
private Queue<Character> chs = new LinkedTransferQueue<Character>();
private Queue<Character> oldchs = new LinkedTransferQueue<Character>();
public void Insert(char ch)
{
if(!chs.contains(ch)&&!oldchs.contains(ch)){
chs.add(ch);
}else{
if(chs.contains(ch)){
chs.remove(ch);
}
if(!oldchs.contains(ch)) {
oldchs.add(ch);
}
}
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
if(chs.isEmpty()){
return '#';
}
return chs.peek();
}
}