zoukankan      html  css  js  c++  java
  • 算法基础(三)

    桶排序、计数排序、基数排序的介绍
    1,非基于比较的排序,与被排序的样本的实际数据状况很有关系,所以实际中并不经常使用

    2,时间复杂度O(N),额外空间复杂度O(N)

    3,稳定的排序

    例子

    给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序

    public static int maxGap(int[] nums){
            if(nums==null||nums.length<2)   return 0;
            int len=nums.length;
            int min=Integer.MAX_VALUE;
            int max=Integer.MIN_VALUE;
            //找出数组中的最大数和最小数
            for (int i = 0; i < len; i++) {
                min=Math.min(min,nums[i]);
                max=Math.max(max,nums[i]);
            }
            //如果数组中只有一种数字,直接返回
            if(min==max)    return 0;
            //记录是否是空桶,true表示不是空桶
            boolean[] hasNum=new boolean[len+1];
            //记录每个桶的最大值和最小值
            int[] maxs=new int[len+1];
            int[] mins=new int[len+1];
            int bid=0;
            for (int i = 0; i < len; i++) {
                bid=bucket(nums[i],len,min,max);
                mins[bid]=hasNum[bid]?Math.min(mins[bid],nums[i]):nums[i];
                maxs[bid]=hasNum[bid]?Math.max(maxs[bid],nums[i]):nums[i];
                hasNum[bid]=true;
            }
            int res=0;
            int lastMax=maxs[0];
            int i=1;
            //找一个非空桶及离它最近的非空桶,后桶的最小值减去前桶的最大值,找出最大差值
            for (; i <=len ; i++) {
                if(hasNum[i]){
                    res=Math.max(res,mins[i]-lastMax);
                    lastMax=maxs[i];
                }
            }
            return res;
        }
        //当前数字属于几号桶
        public static int bucket(long num,long len,long min,long max){
            return (int)((num-min)*len/(max-min));
        }

     题目:用数组结构实现大小固定的栈

    public class ArrayStack {
        private Integer[] arr;
        private Integer index;
        public ArrayStack(int initSize){
            if(initSize<0)
                throw new IllegalArgumentException("the init size is less than 0");
            arr=new Integer[initSize];
            index=0;
        }
        //压栈
        public void push(int obj){
            if(index==arr.length)
                throw new ArrayIndexOutOfBoundsException("the queue if full");
            arr[index++]=obj;
        }
        //返回栈顶,不弹出
        public Integer peek(){
            if(index==0)
                return null;
            return arr[index-1];
        }
        //返回栈顶,弹出
        public Integer pop(){
            if(index==0)
                throw new ArrayIndexOutOfBoundsException("the queue is empty");
            return arr[--index];
        }
    
    }

     题目:用数组结构实现大小固定的队列

    public class ArrayQueue {
        private Integer[] arr;
        private Integer size;
        private Integer start;
        private Integer end;
        public ArrayQueue(int initSize){
            if(initSize<0)
                throw new IllegalArgumentException("the init size is less than 0");
            arr=new Integer[initSize];
            size=0;
            start=0;
            end=0;
        }
        public void push(int obj){
            if(size==arr.length)
                throw new ArrayIndexOutOfBoundsException("the queue is full");
            size++;
            arr[end]=obj;
            end=end==arr.length-1?0:end+1;
        }
        public Integer peek(){
            if(size==0)
                return null;
            return arr[start];
        }
        public Integer poll(){
            if(size==0)
                throw new ArrayIndexOutOfBoundsException("the quere is empty");
            size--;
            int temp=start;
            start=start==arr.length-1?0:start+1;
            return arr[temp];
        }
    }

    题目

      实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。
      【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。 2.设计的栈类型可以使用现成的栈结构

    public class MinStack {
        private Stack<Integer> stackData;
        private Stack<Integer> stackMin;
        public MinStack(){
            stackData=new Stack<Integer>();
            stackMin=new Stack<Integer>();
        }
        public void push(int newNum){
            if(stackMin.isEmpty()){
                stackMin.push(newNum);
            }else if(newNum<getmin()){
                stackMin.push(newNum);
            }else{
                int newMin=stackMin.peek();
                stackMin.push(newMin);
            }
            stackData.push(newNum);
        }
        public int pop(){
            if(stackMin.isEmpty())
                throw new RuntimeException("stack is empty");
            stackMin.pop();
            return stackData.pop();
        }
        public int getmin(){
            if(stackMin.isEmpty()){
                throw new RuntimeException("stack is empty");
            }
            return stackMin.peek();
        }
    }

    题目:如何仅用队列结构实现栈结构?

    public class TwoQueueStack {
        private Queue<Integer> data;
        private Queue<Integer> help;
        public TwoQueueStack(){
            data=new LinkedList<Integer>();
            help=new LinkedList<Integer>();
        }
        public void push(int pushInt){
            data.add(pushInt);
        }
        public int pop(){
            if(data.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            //把data队列的数拿出添加到help,只剩下1个数
            while(data.size()>1) {
                help.add(data.poll());
            }
            //剩下的数,一会返回这个数
            int res=data.poll();
            //data队列是空的,拿出的数都在help中,交换两个队列
            swap();
            return res;
        }
        public int peek(){
            if(data.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            while(data.size()!=1){
                help.add(data.poll());
            }
            int res=data.poll();
            //不弹出,所以重新添加回去
            help.add(res);
            swap();
            return res;
        }
        private void swap(){
            Queue<Integer> tmp=help;
            help=data;
            data=tmp;
        }
    }

    题目:如何仅用栈结构实现队列结构?

    public class TwoStackQueue {
        private Stack<Integer> stackPush;
        private Stack<Integer> stackPop;
        public TwoStackQueue(){
            stackPush=new Stack<Integer>();
            stackPop=new Stack<Integer>();
        }
        public void push(int pushInt){
            stackPush.push(pushInt);
            dao();
        }
        public int poll(){
            if(stackPush.isEmpty()&&stackPop.isEmpty())
                throw new RuntimeException("queue is empty");
            dao();
            return stackPop.pop();
        }
        public int peek(){
            if(stackPush.isEmpty()&&stackPop.isEmpty())
                throw new RuntimeException("queue is empty");
            dao();
            return stackPop.peek();
        }
        public void dao(){
            if(!stackPop.isEmpty()){
                return;
            }
            while (!stackPush.isEmpty()){
                stackPop.push(stackPush.pop());
            }
        }
    }
  • 相关阅读:
    mysql安装及初始密码问题
    centos7上安装erlang22.1
    共享文件夹设置
    putty免密登录
    重新开始
    单任务多线程 安全
    线程池
    多线程
    commons-IO
    打印流
  • 原文地址:https://www.cnblogs.com/huozhonghun/p/10656828.html
Copyright © 2011-2022 走看看