- 逆波兰表达式求值
思路:用栈还是比较简单的,遇到数字就入栈,遇到运算符就弹出栈里的两个元素,需要注意的是-和/的顺序,因为是栈顶下面的那个元素减和除以栈顶元素
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList();
for (String s : tokens) {
if (s.equals("+")) {
stack.push(stack.pop() + stack.pop());
} else if (s.equals("-")) {
// 是前面那个减后面那个
stack.push(-stack.pop() + stack.pop());
} else if (s.equals("*")) {
stack.push(stack.pop() * stack.pop());
} else if (s.equals("/")) {
int temp1 = stack.pop();
int temp2 = stack.pop();
// 注意顺序
stack.push(temp2 / temp1);
} else {
stack.push(Integer.parseInt(s));
}
}
return stack.pop();
}
}
- 滑动窗口最大值 leetcode.com/problems/sl…
思路:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
int n = nums.length;
int[] res = new int[n - k + 1];
int idx = 0;
for(int i = 0; i < n; i++) {
// 根据题意,i为nums下标,是要在[i - k + 1, i] 中选到最大值,只需要保证两点
// 1.队列头结点需要在[i - k + 1, i]范围内,不符合则要弹出
while(!deque.isEmpty() && deque.peek() < i - k + 1){
deque.poll();
}
// 2.既然是单调,就要保证每次放进去的数字要比末尾的都大,否则也弹出
while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offer(i);
// 因为单调,当i增长到符合第一个k范围的时候,每滑动一步都将队列头节点放入结果就行了
if(i >= k - 1){
res[idx++] = nums[deque.peek()];
}
}
return res;
}
}
347.前 K 个高频元素 leetcode.com/problems/to…
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer,Integer> map = new HashMap<>(); //key为数组元素值,val为对应出现次数
for (int num : nums) {
map.put(num, map.getOrDefault(num,0) + 1);
}
//在优先队列中存储二元组(num, cnt),cnt表示元素值num在数组中的出现次数
//出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆)
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2) -> pair2[1] - pair1[1]);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {//大顶堆需要对所有元素进行排序
pq.add(new int[]{entry.getKey(), entry.getValue()});
}
int[] ans = new int[k];
for (int i = 0; i < k; i++) { //依次从队头弹出k个,就是出现频率前k高的元素
ans[i] = pq.poll()[0];
}
return ans;
}
}