150.逆波兰表达式求值
逆波兰表达式:二叉树的后序遍历,又称后缀表达式
思路:新建一个栈,遍历所给字符串,遇到数字加入栈,一旦遇到运算符号,就从栈中取出两个数,再将运算后的数重新加入栈中,直到将字符串遍历完,栈中最后一个值就是要返回的。
使用栈(Stack<int>
)来保存中间结果。
遍历 tokens:
-
是数字:入栈。
-
是操作符:出栈两个元素(先出的是右操作数),计算结果再入栈。
遍历结束后,栈顶元素就是结果。
注意点:
-
int.Parse(token) → 字符串转换成整数
-
在运算时注意a,b的顺序,应该是b在前
-
在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),维护窗口中的值对应的下标
步骤总结:
-
使用一个双端队列
deque
,存放元素的 下标,并维持队列中值对应的顺序单调递减。 -
遍历数组的每个元素
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 个高频元素
思路:堆
-
统计元素频率:使用哈希表(
Dictionary<int, int>
)记录每个元素的出现次数。 -
维护最小堆:使用优先队列(
PriorityQueue<int, int>
)维护当前频率最高的 K 个元素。队列的优先级由元素的频率决定,频率最低的元素位于堆顶。 -
输出结果:遍历优先队列,按频率从高到低输出元素(通过逆序填充数组实现)。
优先队列(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;
}
}