Android开发Android技术知识

算法入门(二)

2019-09-29  本文已影响0人  拨云见日aaa

一、习题练习

(1)数组排序之后相邻的最大差值

public class MaxGap {
        public static int maxGap(int[] arr){
            
        if(arr==null||arr.length<2){
        return 0;
        }
        int length=arr.length;
        int max=arr[0];
        int min=arr[0];
        for(int i=1;i<arr.length;i++){
        max=Math.max(max,arr[i]);
        min=Math.min(min,arr[i]);
        }
        if(max==min){
        return 0;
        }
        int index=0;
        boolean[] isHave=new boolean[length+1];
        int[] maxbuk=new int[length+1];
        int[] minbuk=new int[length+1];
        for(int i=0;i<length;i++){
        index=getIndex(length,arr[i],max,min);
        maxbuk[index]=isHave[index]?Math.max(maxbuk[index],arr[i]):arr[i];
        minbuk[index]=isHave[index]?Math.min(minbuk[index],arr[i]):arr[i];
        isHave[index]=true;
        }
        int lastMax=maxbuk[0];
        int res=0;
        for(int j=1;j<length+1;j++){
        if(isHave[j]){
        res=Math.max(res,minbuk[j]-lastMax);
        lastMax=maxbuk[j];
        }
        }
        return res;
        }
        public static int getIndex(int length,int number,int max,int min){
        return (int)((number-min)*length/(max-min));
        }
        }

(2)用数组实现栈结构

public class MyStack{
    int[] stack;
int index=0;
public MyStack(int initSize){
    stack=new int[initSize];
}


public void push(int number){
if(index==stack.length){
    System.out.print("满了");
throw new RuntimeException("已经满了");
}
stack[index++]=number;
}
public int pop(){
if(index==0){
throw new RuntimeException("已经空了");
}
return stack[--index];
}
public int peek(){
if(index==0){
throw new RuntimeException("已经空了");
}
return stack[index-1];
}
}

(3)用数组实现队列结构

public class MyQueue {
    
        int start=0;
        int end=0;
        int size=0;
        int[] queue;
        public MyQueue(int initSize){
        queue=new int[initSize];
        }
        public void push(int num){
        if(size==queue.length){
        throw new RuntimeException("队列已满");
        }
        queue[end]=num;
        end=end+1==queue.length?0:end+1;
        size++;
        }
        public int pop(){
        if(size==0){
        throw new RuntimeException("队列是空的");
        }
        int res=queue[start];
        size--;
        start=start+1==queue.length?0:start+1;
        return res;
        }
        public int peek(){
        if(size==0){
        throw new RuntimeException("队列是空的");
        }
        return queue[start];
        }
        }

(4)实现一个特殊的栈,在实现栈的最基本功能的基础上,在实现返回栈中最小元素的功能

  1. 当入栈时如果minStack为空直接把数压进minStack里,如果不为空比较进来的数和minStack栈顶的数大小,如果进来的数小或等于压进栈minStack,如果大则不做任何操作。当出栈时,出栈的数和minStack栈顶的数比较大小,如果大minStack不做任何操作,如果等于minStack出栈。getmin方法就返回minStack栈顶的元素。这种方式比较省空间,但是出栈麻烦一些。

  2. 当入栈时,若minStack为空,则直接压进minStack中,若不为空,和栈顶的数比较大小,如果大于栈顶把minStack栈顶的数重复压一遍,若小于等于直接压入栈中。当出栈时,和dataStack同步出栈就可以了。getmin方法就返回minStack栈顶的元素。这种方法稍微浪费空间,但出栈简单。

public class SpecialStack {
Stack<Integer> dataStack=new Stack<>();
Stack <Integer>minStack=new Stack<>();
public void push(int number) {
    dataStack.push(number);
    if(minStack.isEmpty()) {
        minStack.push(number);
    }else {
        int top=minStack.peek();
        if(number<=top) {
            minStack.push(number);
        }
    }
}
public int pop(){
    int popData=dataStack.pop();
    if(popData==minStack.peek()) {
        minStack.pop();
    }
    return popData;
}
public int getMin() {
    
    return minStack.peek();
}
}

方案二

public class SpecialStack2 {
Stack<Integer> dataStack=new Stack<>();
Stack <Integer>minStack=new Stack<>();
public void push(int number) {
    dataStack.push(number);
    if(minStack.isEmpty()) {
        minStack.push(number);
    }else {
        int top=minStack.peek();
        if(number<=top) {
            minStack.push(number);
        }else {
            minStack.push(top);
        }
    }
}
public int pop(){
    minStack.pop();
    return dataStack.pop();
}
public int getMin() {
    
    return minStack.peek();
}
}

(5)使用队列实现栈结构

public class QueueToStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
public QueueToStack() {
    queue1=new LinkedList<>();
    queue2=new LinkedList<>();
}
public void push(int number) {
    queue1.add(number);
}
public int pop() {
    if(queue1.isEmpty()) {
        throw new RuntimeException("栈已空");
    }
    while(queue1.size()!=1) {
        queue2.add(queue1.poll());
    }
    int res=queue1.poll();
    swap();
    return res;
}
public int peek() {
    if(queue1.isEmpty()) {
        throw new RuntimeException("栈已空");
    }
    while(queue1.size()!=1) {
        queue2.add(queue1.poll());
    }
    int res=queue1.poll();
    queue2.add(res);
    swap();
    return res;
}
public void swap() {
    Queue<Integer> temp;
    temp=queue1;
    queue1=queue2;
    queue2=temp;
}
}

(6)用栈实现队列

-代码示例

public class StackToQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public StackToQueue() {
    stack1=new Stack<>();
    stack2=new Stack<>();
}
public void add(int number) {
    stack1.push(number);
}
public int poll() {
    if(stack2.isEmpty()) {
        while(stack1.size()!=0) {
            stack2.push(stack1.pop());
        }
    }
    return stack2.pop();
}
public int peek() {
    if(stack2.isEmpty()) {
        while(stack1.size()!=0) {
            stack2.push(stack1.pop());
        }
    }
    return stack2.peek();
}
}

(7)猫狗队列问题

实现一种猫狗队列的结构,要求如下:
用户可以调用add方法将猫或狗的实例放入队列中
用户可以调用pollAll方法将队列中所有实例按照进队列的先后顺序依次弹出
用户可以调用pollDog方法将队列中的狗类按照进队列的先后顺序依次弹出
用户可以调用pollCat方法将队列中的猫类按照进队列的先后顺序依次弹出
用户可以调用isEmpty方法,检查队列中是否还有dog或者cat的实例存在
用户可以调用isDogEmpty方法,检查队列中是否还有dog的实例存在
用户可以调用isCatEmpty方法,检查队列中是否还有cat的实例存在

猫狗封装类
class QueueEnter{
    private Pet pet;
    private int count;
    public QueueEnter(Pet pet,int count) {
        this.pet=pet;
        this.count=count;
    }
    public Pet getPet() {
        return pet;
    }
    public int getCount() {
        return count;
    }
}

猫狗队列

public class DogAndCatQueue {
int count=0;
Queue<QueueEnter> dogQueue;
Queue<QueueEnter> catQueue;
public DogAndCatQueue() {
    dogQueue=new LinkedList<>();
    catQueue=new LinkedList<>();
}
public void add(Pet pet) {
    if(pet.getType().equals("dog")){
        dogQueue.add(new QueueEnter(pet,count++));
    }else {
        catQueue.add(new QueueEnter(pet,count++));
    }
}
public Pet pollAll() {
    if(dogQueue.isEmpty()&&catQueue.isEmpty()) {
        throw new RuntimeException("队列已空");
    }
    if(dogQueue.isEmpty()) {
        return (Cat)catQueue.poll().getPet();
    }
    if(catQueue.isEmpty()) {
        return (Dog)dogQueue.poll().getPet();
    }
    int dogCount=dogQueue.peek().getCount();
    int catCount=catQueue.peek().getCount();
    if(dogCount<catCount) {
        return (Dog)dogQueue.poll().getPet();
    }else {
        return (Cat)catQueue.poll().getPet();
    }
}
public Pet pollDog() {
    if(dogQueue.isEmpty()) {
        throw new RuntimeException("队列中已没有dog实例");
    }
    return (Dog)dogQueue.poll().getPet();
}
public Pet pollCat() {
    if(catQueue.isEmpty()) {
        throw new RuntimeException("队列中已没有cat实例");
    }
    return (Cat)catQueue.poll().getPet();
}
public boolean isEmpty() {
    if(dogQueue.isEmpty()&&catQueue.isEmpty()) {
        return false;
    }else {
        return true;
    }
}
public boolean isDogEmpty() {
    return dogQueue.isEmpty();
}
public boolean isCatEmpty() {
    return catQueue.isEmpty();
}
public int size() {
    return dogQueue.size()+catQueue.size();
}
}

二、拓展

综合排序,当数据量大时,首先用归并或者快速排序,当递归到数量小于一定数量以后直接用插入排序排,选择归并还是快速排序看数据是否是基本类型,当是基本类型时用快速排序,因为快排不具备稳定但速度更快,而且基本类型也不需要稳定性,当是非基本类型时,用归并排序,归并排序稳定性高

上一篇 下一篇

猜你喜欢

热点阅读