今日刷三题(day7):数据流中的中位数+有效括号序列+数组中超过一半的数字

题目一:数据流中的中位数

题目描述:

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

输入输出描述:

输入:[5,2,3,4,1,6,7,0,8]        返回值:"5.00 3.50 3.00 3.50 3.00 3.50 4.00 3.50 4.00 "
说明:
数据流里面不断吐出的是5,2,3...,则得到的平均数分别为5,(5+2)/2,(5+2+3)/3...

思路解析:

中位数是数组中最中间的一个数或中间两个数的均值。是数组较小元素中最大的一个,也是数组较大元素中最小的一个,每次维护最小的一半元素和最大的一半元素,并能快速得到它们的最大值和最小值。这里我们可以采用优先级队列(构建小堆和大堆并维护)。

作答情况:

未做出,没有想到使用两个堆。

代码:

import java.util.*;


public class Solution {
//(大根堆)4,3,2,1 //(小根堆)6,7,8,9

 //小根堆,存储元素特征:元素最小的值都比大根堆最大值大
PriorityQueue<Integer> minNum=new PriorityQueue<>();
//大根堆,存储元素特征:元素的最大值都比小根堆最小值小
PriorityQueue<Integer> maxNum=new PriorityQueue<>((o1,o2)->(o2-o1));
    public void Insert(Integer num) {//num=5
   if(maxNum.size()==minNum.size()){
    //先加入较小部分
minNum.add(num);
//将较小部分的最大值取出,送入到较大部分(成为较大部分最大值)
maxNum.add(minNum.poll());//5,4,3,2,1
   }
   //相反
   else{
    maxNum.add(num);
    minNum.add(maxNum.poll());
   }
    }

    public Double GetMedian() {
        if(maxNum.size()==minNum.size()){
            return (maxNum.peek()+minNum.peek())/2.0;
        }else{
            return maxNum.peek()*1.0;//奇数时大顶堆会多一个
        }
    }
}

题目二:有效括号序列

题目描述:

给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。

输入输出描述:

输入:"[]"                      返回值:true

输入:"[()}"                      返回值:false

思路解析:

辅助栈+右括号入栈。

step1:  当遇到'(','[','{'这三种字符的时候则让对应的匹配字符入栈(分别对应')',']','}')

step2:  当出现的字符不是'(','[','{'这三种字符时,则先判断栈是否为空或者当前字符是否与栈顶元素一样。

step3:当栈空或者当前字符与栈顶字符不一样时,则括号序列不合法,直接返回;否则栈顶元素出栈。遍历字符串直到所有元素遍历完成。

step4:  最后判断栈是否为空,不为空则括号序列不合法;否则为合法序列。

作答情况:

正确。

代码:

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    public boolean isValid (String s) {
     //辅助栈
     Stack<Character> stack=new Stack<>();
     for(int i=0;i<s.length();i++){
       if(s.charAt(i)=='(')    stack.add(')');
       else if(s.charAt(i)=='[')    stack.add(']');
       else if(s.charAt(i)=='{')     stack.add('}');
       //当字符不是'(','[','{'这三种字符时,则判断栈是否为空和当前字符是否与栈顶元素一样
       else if(stack.isEmpty()||stack.pop()!=s.charAt(i)) return false;
     }
     return stack.isEmpty();
    }
}

题目三:数组中出现超过一半的数字

题目描述:

给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

输入输出描述:

保证数组输入非空,且保证有解。

输入:[1,2,3,2,2,2,5,4,2]       返回值:2

输入:[1]                                返回值:1

思路解析:

"哈希算法"。

step1:设置一个哈希<键,值>;键里面存储数组元素,值里面存储数组元素出现的次数。

step2:  遍历一遍数组,如果没有遇到过该数组元素,出现次数为1;遇到过该数组元素,出现次数累加。

step3:再遍历一遍数组,通过数组的值映射出次数,如果超过数组长度一半,返回。

作答情况:

正确。

代码:

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param numbers int整型一维数组 
     * @return int整型
     */
    public int MoreThanHalfNum_Solution (int[] numbers) {
      if(numbers.length<=1) return numbers[0];
      HashMap<Integer,Integer> map=new HashMap<>();
      for(int i=0;i<numbers.length;i++){
        if(!map.containsKey(numbers[i])){//是否包含numbers[i]对应的键
            map.put(numbers[i],1);
        }
        else {
            map.put(numbers[i],map.get(numbers[i])+1);
        }
      }
      for(int i=0;i<numbers.length;i++){
        if(map.get(numbers[i])>numbers.length/2){
            return numbers[i];
        }
      }
    return -1;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值