Day11| 150.逆波兰表达式求值、239. 滑动窗口顶部

150.逆波兰表达式求值

逆波兰表达式:二叉树的后序遍历,又称后缀表达式

思路:新建一个栈,遍历所给字符串,遇到数字加入栈,一旦遇到运算符号,就从栈中取出两个数,再将运算后的数重新加入栈中,直到将字符串遍历完,栈中最后一个值就是要返回的。

使用栈(Stack<int>)来保存中间结果。

遍历 tokens:

  • 是数字:入栈。

  • 是操作符:出栈两个元素(先出的是右操作数),计算结果再入栈。

遍历结束后,栈顶元素就是结果。

注意点:

  1. int.Parse(token) → 字符串转换成整数

  2. 在运算时注意a,b的顺序,应该是b在前

  3. 在C#中,方法开头字母注意是大写字母

public class Solution {
    public int EvalRPN(string[] tokens) {
        Stack<int> stack=new Stack<int>();
        foreach(var i in tokens){
            if(i=="+"||i=="-"||i=="*"||i=="/"){
                int a = stack.Pop();
                int b = stack.Pop();
                int result = i switch{
                    "+"=>b+a,
                    "-"=>b-a,
                    "/"=>b/a,
                    "*"=>b*a,
                };
                stack.Push(result);
            }
            else{
                stack.Push(int.Parse(i));
            }
        }
        return stack.Pop();
    }
}

239. 滑动窗口顶部

单调队列法:用一个双端队列(Deque)维护窗口中的值对应的下标

步骤总结:

  1. 使用一个双端队列 deque,存放元素的 下标,并维持队列中值对应的顺序单调递减

  2. 遍历数组的每个元素 nums[i]

  • 弹出所有比 nums[i] 小的元素下标(它们不可能是未来窗口的最大值)。

  • i 加入队列尾部。

  • 如果队首元素的下标已经不在窗口内了(i - k >= deque[0]),则弹出队首。

  • i >= k - 1 时(窗口形成),将队首所指的元素加入结果数组。

操作类型操作说明操作方向
加入元素AddLast(i) ⇒ 把当前元素的索引加入✅ 队尾
移除小值RemoveLast() ⇒ 移除比当前值小的索引✅ 队尾
移除过期值RemoveFirst() ⇒ 移除滑出窗口左边的值✅ 队首
获取最大值nums[deque.First.Value]✅ 队首
public class Solution {
    public int[] MaxSlidingWindow(int[] nums, int k) {
        if(nums==null||nums.Length<k||k<0){
            return new int[0];
        }
        var deque = new LinkedList<int>();
        var result = new List<int>();

        for(int i=0;i<nums.Length;i++){
            // 删除队列中小于当前值的元素(从队尾开始)
            while(deque.Count>0&&nums[i]>nums[deque.Last.Value]){
                deque.RemoveLast();
            }
            deque.AddLast(i);
            // 移除窗口外的元素(超出窗口左边界)
            if(deque.First.Value<=i-k){
                deque.RemoveFirst();
            }
            // 当窗口形成时,记录窗口最大值(队首)
            if(i>=k-1){
                result.Add(nums[deque.First.Value]);
            }
        }
        return result.ToArray();
    }
}

347.前 K 个高频元素

思路:堆

  1. 统计元素频率:使用哈希表(Dictionary<int, int>)记录每个元素的出现次数。

  2. 维护最小堆:使用优先队列(PriorityQueue<int, int>)维护当前频率最高的 K 个元素。队列的优先级由元素的频率决定,频率最低的元素位于堆顶。

  3. 输出结果:遍历优先队列,按频率从高到低输出元素(通过逆序填充数组实现)。

优先队列(PriorityQueue<TElement, TPriority>

  • 作用:基于最小堆(默认)实现,动态维护 Top K 元素。

  • 核心 API:

  • Enqueue(element, priority):插入元素并按优先级排序。

  • Dequeue():移除并返回优先级最低的元素(堆顶)。

  • 特点:

  • 堆操作的时间复杂度为 O(logk),适合处理海量数据的 Top K 问题。

  • 与直接排序(O(nlogn))相比,空间效率更高(仅维护 K 个元素)。

public class Solution {
    public int[] TopKFrequent(int[] nums, int k) {
        //哈希表map
        Dictionary<int,int> dic = new();
        for(int i=0;i<nums.Length;i++){
            if(dic.ContainsKey(nums[i])){
                dic[nums[i]]++;
            }
            else{
                dic.Add(nums[i],1);
            }
        }
        //优先队列-从小到大排列
        PriorityQueue<int,int> pq=new();
        foreach(var num in dic){
            pq.Enqueue(num.Key,num.Value);
            if(pq.Count>k){
                pq.Dequeue();
            }
        }
        //数组输出
        int[] res = new int[k];
        for(int i=k-1;i>=0;i--){
            res[i]=pq.Dequeue();
        }
        return res;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值