LeetCode实现20 有效的括号,739每日的温度

学习目标:栈与实现

掌握栈的实现,完成leetCode 20题 有效的括号
739.每日的温度


学习内容:

1、数组实现栈 2、 链表实现栈 3、 完成 20题 有效的括号 4、739.每日的温度

题目:

1、 有效的括号:

给定一个只包括(,),{,},[,] 的字符串,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2 左括号必须以正确的顺序闭合。

  • 注意空字符串可被认为是有效字符串。
    示例1 :
    输入:"()"-输出:true
    输入:"(]"- 输出:false

2、 每日温度

根据每日气温列表,请重新生成一个列表,对应位置的输入是你需要在等待多久温度才会升高超过该日的天数,如果之后都不会升高,请在该位置用0代替。
提示:
气温列表temp 的长度范围为是【1,30000】。
示例:
temp= [23,24,25,21,19,22,26,23]
输出 :[1,1,4,2,1,1,0,0]


学习产出:

1、 数组实现栈代码 2、 链表实现栈代码 3、 有效的括号实现代码 4、 每日温度实现代码


一、栈的实现

栈:先进后出,实现方法入栈,出栈,栈顶元素,是否为空,栈深,清理栈。

/**
 * @author 
 * @create 2020-08-23 14:46
 */
public interface StackInterface<T> {
    /*
    * 出栈的方法*/
    T pop();

    /*入栈的方法*/
   void push(T t);

   /*获取栈定元素的方法*/
    T peek();

    /*判断是否为空*/

    boolean isEmpty();

    /* 清理栈*/
    void clear();
    /*当前栈深度*/
    int length();
}

数组实现栈:方便查找,由于有扩容问题,数量越大,速度越慢。

/**
 * @author 
 * @create 2020-08-23 14:52
 */
public class MyArrayStack<T> implements StackInterface<T> {
    private  final int DEFAULT_STACK_SIZE=8;
    int n=0; // 栈针
    T[] StackData=null;

    public MyArrayStack(){
        StackData =(T[])new Object[DEFAULT_STACK_SIZE];
    }

    @Override
    public T pop() {
        if (isEmpty()){
            return  null;
        }else{
          T m= StackData[--n];
            StackData[n]=null;
            if (n!=0&&StackData.length/n==4){
                // 对数组长度减半
                this.ArrayDouble();
            }

            return m;
        }
    }

    @Override
    public void push(T t) {
        StackData[n++]=t;
        if (n==StackData.length){
            // 对数组进行扩容
            this.ArrayDouble();
        }
    }

    @Override
    public T peek() {
        if (isEmpty()){
            return  null;
        }else{
            T m= StackData[--n];
            n++;
            return m;
        }
    }

    @Override
    public boolean isEmpty() {
        return n==0;
    }

    @Override
    public void clear() {
        StackData=null;
    }

    @Override
    public int length() {
        return n;
    }

    /*
    *  数组扩容
    * */
    private void ArrayDouble(){
        T [] newStackData = (T[]) new Object[n*2];
        System.arraycopy(StackData,0,newStackData,0,n);
        StackData =newStackData;
    }
}

链表实现栈:无扩容问题,比较推荐的实现,这里使用的是我自己实现的单链表。各位同学们可以使用 LinkedList 实现。

package learn.stack;


/**
 * @author 
 * @create 2020-08-23 16:15
 */
public class MyLinkStack<T> implements StackInterface<T> {

    private  MyLinkedList<T> linkstack=new MyLinkedList<T>();
    @Override
    public T pop() {
        Node m=linkstack.getLastNode();
        linkstack.deleteNode(linkstack.length());
        return (T) m.data;
    }

    @Override
    public void push(T t) {
        linkstack.addNode(t);
    }

    @Override
    public T peek() {
        Node m=linkstack.getLastNode();
    //    linkstack.deleteSpecialNode(m);
        return (T) m.data;
    }

    @Override
    public boolean isEmpty() {
       return linkstack.length()==0;
    }

    @Override
    public void clear() {
        linkstack.deleteNode(1);
    }

    @Override
    public int length() {
        return linkstack.length();
    }
}

二、实现有效的括号

分析:

1 "" 是一个有效字符串
2 11 匹配
3 顺序需要一致。

用栈比较合适
1 遇到左面括号入栈
2 遇到右面括号与栈顶配对。成功栈顶出栈。失败返回 false
3 判断栈是否为空。否,返回false。

代码实现:

 public static boolean ifable(String m) {
        boolean flag = true;
        if ("".equals(m)) {
            return flag;
        }

        //   MyArrayStack<String> stack =new MyArrayStack<String>();
        MyLinkStack<String> stack = new MyLinkStack<String>();

        String[] marr = m.split(",");
        for (String i : marr) {
            if (i.equals("(") || i.equals("[") || i.equals("{")) {
                stack.push(i);
            } else if (stack.peek() == null) {
                flag = false;
                break;
            } else if (i.equals(")")) {
                if (!stack.peek().equals("(")) {
                    flag = false;
                    break;
                } else {
                    stack.pop();
                }
            } else if (i.equals("]")) {
                if (!stack.peek().equals("[")) {
                    flag = false;
                    break;
                } else {
                    stack.pop();
                }
            } else if (i.equals("}")) {
                if (!stack.peek().equals("{")) {
                    flag = false;
                    break;
                } else {
                    stack.pop();
                }
            } else {
                flag = false;
                break;
            }
        }
        if (!stack.isEmpty()) {
            flag = false;
        }
        return flag;
    }

三、实现每日温度

分析:

1 记录的过几日升高的温度。正是数组下标相减的值,这里肯定会想到双for循环。时间复杂度O()
2 数组应该倒着循环
3 栈记录数组的下标
4 数组元素大于栈顶对应的数组元素出栈
5 栈顶元素减循环值i

代码实现:

public static int[] weatherStatistics(int[] weatherArr) {
        int[] statistics = new int[weatherArr.length];
        MyLinkStack<Integer> myStack = new MyLinkStack<Integer>();
        for (int i = weatherArr.length - 1; i >= 0; i--) {
            while (!myStack.isEmpty() && weatherArr[i] >= weatherArr[myStack.peek()]) {
                myStack.pop();
            }
            // 如果栈为空,则结果为0
            // 如果栈不为空,则用当前栈顶存储的温度
            statistics[i] = myStack.isEmpty() ? 0 : (myStack.peek() - i);
            // 让当前的温度入栈
            myStack.push(i);
        }
        return statistics;
    }

调用:

 public static void main(String[] args) {
//        String m = "(,),{,},[,]";
//        // m="(,[,[,{,},],),[,(,),],(,{,[,],},)";
//        boolean n = ifable(m);
//        System.out.println(n);
        int[] test = new int[]{23, 24, 25, 21, 19, 22, 26, 23};
        int[] result = weatherStatistics(test);
        for (int i : result) {
            System.out.print(i + ",");
        }
    }

总结

关于每日温度的实现,参考了大佬栈实现的代码。每日温度使用栈实现时间复杂度O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值