算法基础(三)

桶排序、计数排序、基数排序的介绍
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());
        }
    }
}

 

posted @ 2019-04-05 17:52  程序员Forlan  阅读(258)  评论(0编辑  收藏  举报