桶排序、計數排序、基數排序的介紹
1,非基於比較的排序,與被排序的樣本的實際數據情況頗有關係,因此實際中並不常用 數組
2,時間複雜度O(N),額外空間複雜度O(N) less
3,穩定的排序spa
例子設計
給定一個數組,求若是排序以後,相鄰兩數的最大差值,要求時 間複雜度O(N),且要求不能用非基於比較的排序code
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)); }
題目:用數組結構實現大小固定的棧blog
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.設計的棧類型能夠使用現成的棧結構get
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(); } }
題目:如何僅用隊列結構實現棧結構?it
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()); } } }