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

Posted 诗萧尘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)。

以上是关于LeetCode实现20 有效的括号,739每日的温度的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode-739.每日温度(双思路分析)

每日LeetCode一道题————有效的括号(括号匹配)

LeetCode 739. 每日温度

Java算法 每日一题 编号20:有效的括号

Java算法 每日一题 编号20:有效的括号

Java算法 每日一题 编号20:有效的括号