Week03

本文探讨了两个算法问题,一是如何计算给定的算术表达式,包括加减乘除操作,二是如何根据每日气温列表计算出升高的天数。对于计算器问题,解决方案涉及去除空格,存储数字和运算符,然后通过栈处理乘除优先级。对于每日温度问题,采用双指针方法计算等待天数。这两个问题都展示了有效的算法思维和数据结构应用。
摘要由CSDN通过智能技术生成
第一题:计算器

链接: https://leetcode-cn.com/problems/calculator-lcci/.
题号:leetcode面试16-26
难度:medium

给定一个包含正整数、加(+)、减(-)、乘()、除(/)的算数表达式(括号除外),计算其结果。
表达式仅包含非负整数,+, - ,
,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: “3+2*2”
输出: 7 示例 2:

输入: " 3/2 "
输出: 1 示例 3:

输入: " 3+5 / 2 "
输出: 5

说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

思路:

1.首先需要去除字符串中的空格。遍历字符串,使用list集合存储数字和加减乘除。 注意:需要判断数字的结束位置,进行截取。因为数字长度不是唯一,数字存储只能存储一个整体,但是加减乘除是字符。所以
list泛型为String。
2.存储list结束,观察list集合与之前的区别是,集合中都是数字字符串和加减乘除字符串。因为乘除优先级最高且相等。 可以利用栈stack来进行乘除计算。遍历list集合,遇到数字和加减符号进栈。遇到乘除符号,弹栈一个元素,与list集合下一个数字进行乘除运算
后进栈。
3.观察stack栈。栈中元素只有数字和加减符号。但是出栈顺序和计算顺序是反着的。需要第二个栈stack1将stack栈中元素存储。
4.观察stack1栈。此时栈中出栈顺序和计算顺序一致。遇到数字弹栈,遇到字符进行加减

public class Solution {
    public int calculate(String s) {
        //1.去除空格,截取数字和运算符号,存储在list集合。
        List<String> list = new ArrayList<>();
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i) == ' ') continue;   //遍历字符串,遇到空格跳过不存储
            if(s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '*' || s.charAt(i) == '/'){
                //遇到加减乘除字符,直接添加存储
                list.add(String.valueOf(s.charAt(i)));
            }else{
                int start = i;  //遇到数字,记录下数字开始下标
                //找到数字结束位置,注意,判断i是否越界,i<s.length()需要放在最前面,当i不成立的时候循环结束,不然s.charAt(i)会越界
                while(i<s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9'){
                    i++;
                }
                int end = i;
                String num = s.substring(start,end);  //截取数字字符串
                list.add(num);
                i--;  //注意,这个地方,需要i--。在进入for循环中,i++才能到达正确下标
            }
        }
        //2.乘除优先级高,优先计算乘除
        Stack<String> stack = new Stack<>();
        for(int i=0; i<list.size(); i++){
            if(list.get(i).equals("*")){
                int tem = Integer.parseInt(stack.pop()) * Integer.parseInt(list.get(i+1));
                stack.push(String.valueOf(tem));
                i++;
            }else if(list.get(i).equals("/")){
                int tem = Integer.parseInt(stack.pop()) / Integer.parseInt(list.get(i+1));
                stack.push(String.valueOf(tem));
                i++;
            }else{
                stack.push(list.get(i));
            }
        }
        //3.栈中只剩下加减符号和数,但是栈的数据是反着的,再次进栈
        Stack<String> stack1 = new Stack<>();
        while(!(stack.empty())){
            stack1.push(stack.pop());
        }
        //4.弹栈计算最终结果
        int sum=0;
        while(!(stack1.empty())){
            String ss = stack1.pop();
            if(ss.equals("+")){
                sum = sum + Integer.parseInt(stack1.pop());
            }else if(ss.equals("-")){
                sum = sum - Integer.parseInt(stack1.pop());
            }else{
                sum = sum + Integer.parseInt(ss);
            }
        }
        return sum;
    }
}

第二题:每日温度

链接: https://leetcode-cn.com/problems/daily-temperatures/.
题号:leetcode739
难度:medium

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

思路:

1.边界判断,如果只有一个元素,直接返回T,其中T[0] = 0
2.双指针i和j,使用双循环。 i负责遍历数组,j负责遍历i指针后面的数组,和i下标下的元素比较大小。count计数记录比较过程。时间复杂度O(n2),空间复杂度O(1)

class Solution {
    public int[] dailyTemperatures(int[] T) {
        //1.边界判断,如果只有一个元素,直接返回T,其中T[0] = 0
        if(T.length == 1){
            T[0] = 0;
            return T;
        }
        //2.双指针,i和j。 i负责遍历数组,j负责遍历i指针后面的数组,和i下标下的元素比较大小
        //count计数记录比较过程
        for(int i=0; i<T.length; i++){
            int count = 0;
            for(int j=i; j<T.length; j++){
                if(T[i] < T[j]){
                    T[i] = count;
                    break;
                }else if(j == T.length-1){
                    T[i] = 0;
                    break;
                }else{
                    count++;
                }
            }
        }
        return T;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值