150. 逆波兰表达式求值
题目:150. 逆波兰表达式求值 - 力扣(LeetCode)
题解:代码随想录
状态:AC
思路
利用栈的性质即可解决,但要注意判断字符串相等时需要用equals
代码
时间复杂度:O(n) 空间复杂度:O(n)
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < tokens.length; i++){
if(tokens[i].equals("+")){
stack.push(stack.pop() + stack.pop());
}else if(tokens[i].equals("-")){
stack.push(- stack.pop() + stack.pop());
}else if(tokens[i].equals("*")){
stack.push(stack.pop() * stack.pop());
}else if(tokens[i].equals("/")){
int a = stack.pop(), b = stack.pop();
stack.push(b / a);
}else{
stack.push(Integer.parseInt(tokens[i]));
}
}
return stack.pop();
}
}
239. 滑动窗口最大值
题目:239. 滑动窗口最大值 - 力扣(LeetCode)
题解:代码随想录
状态:需要多复习
思路
单调队列
- 一个双端队列,当新加入元素比队尾元素大时,循环移除队尾元素直到没有比新入元素大的元素为止;
- 之后新元素索引入队;
- 判断当前队头元素是否超出队列大小限制(K),超出则移除队头;
- 期间用一个idx索引中间变量记录res数组索引位置,当队列首次达到k后开始将结果放入res数组
代码
时间复杂度:O(n) 空间复杂度:O(n)
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length - k + 1];
int idx = 0;
Deque<Integer> q = new LinkedList<>();
for(int i = 0; i < nums.length; i++){
while(!q.isEmpty() && nums[i] >= nums[q.getLast()]){
q.removeLast();
}
q.offer(i);
if(i - q.peek() >= k){
q.poll();
}
if(i >= k - 1){
res[idx++] = nums[q.peek()];
}
}
return res;
}
}
347.前 K 个高频元素
题目:347. 前 K 个高频元素 - 力扣(LeetCode)
题解:代码随想录
状态:需要多复习
思路
优先队列
- 维护一个大小为k的小顶堆,当加入的元素比队头大时就移除队头
- 最后队列中剩下的元素就是答案
代码
时间复杂度:O(nlogn) 空间复杂度:O(n)
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2) -> pair1[1] - pair2[1]);
for(var entry : map.entrySet()){
if(pq.size() < k){
pq.add(new int[]{entry.getKey(), entry.getValue()});
} else{
if(entry.getValue() > pq.peek()[1]){
pq.poll();
pq.add(new int[]{entry.getKey(), entry.getValue()});
}
}
}
int[] ans = new int[k];
for(int i = k - 1; i >= 0; i--){
ans[i] = pq.poll()[0];
}
return ans;
}
}