java
1、string
string转换为int
Integer.valueOf(s)
字符串对比
s1.equals(s2)
2、优先队列
PriorityQueue
import java.util.PriorityQueue;
PriorityQueue<Integer> q1 = new PriorityQueue<>();
注意:默认情况下,PriorityQueue队列是小堆,如果需要大堆需要用户提供比较器
150. 逆波兰表达式求值
思路:借助栈,遇到数字压入栈,遇到操作符弹出栈顶两个元素进行操作并压入栈。
错误点:
①题目中给的逆波兰表达式是用 String[] tokens存储的。涉及到string转换为int:Integer.valueOf(s)
②本来想把 "+"(string)转换为 '+'(string),但不用这么干,本质是想对比是否相同,直接用字符串对比就可以。
③字符串对比 s1.equals(s2)
④如果操作符是减法或者除法,操作数的顺序 和 栈顶弹出元素 是相反的。
正确写法:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
//如果是数字,入栈
//如果是符号,弹出栈顶两个元素运算,且还要把结果压回栈
for(int i=0; i<tokens.length; i++) {
String s = tokens[i];
//string转换为int ? 不需要
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("/")) {
// stack.push(stack.pop()/stack.pop()); //错了
int tmp1 = stack.pop();
int tmp2 = stack.pop();
stack.push(tmp2/tmp1);
} else {//数字
// stack.push(s);
stack.push(Integer.valueOf(s));
}
}
return stack.pop();
}
}
239. 滑动窗口最大值
单调队列
347.前 K 个高频元素
思路难点:①怎么求数组中每个元素的频率②怎么对频率进行排序
可以使用map元素,key存放元素,,value存放频率,对value进行排序,按快排的时间复杂度,nlogn
但我们没有必要对所有元素进行排序,只需要对k个进行排序。
【大顶堆、小顶堆】:适合在大数据集里,求k个高频、低频元素。堆底层实现是二叉树,大顶堆:根元素大于子元素数值。 时间复杂度:nlogk(n用堆遍历一遍数组,logk:在堆每加入一个元素)
优先级队列就是大顶堆和小顶堆。
class Solution {
public int[] topKFrequent1(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;
}
}