提示:这里可以添加本文要记录的大概内容:
本文章记录自己刷牛客网算法面试必刷TOP101——堆/栈/队列,部分类容,参见牛客网地址:面试必刷TOP101——堆/栈/队列,总共有8道题目。
提示:以下是本篇文章正文内容
题目:
代码:
public class BM42 {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if (stack2.isEmpty()) {
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
题目:
代码:
public class BM43 {
// 利用两个栈
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
public void push(int node) {
stack1.push(node);
if (stack2.isEmpty() || stack2.peek() >= node) {
stack2.push(node);
}
}
public void pop() {
int pop = stack1.pop();
if (stack2.peek() == pop) {
stack2.pop();
}
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}
题目:
代码:
public class BM44 {
public boolean isValid(String s) {
// write code here
char[] arr = s.toCharArray();
// 栈保存的是右括号
Stack<Character> stack = new Stack<>();
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
if (c == '{') {
stack.push('}');
} else if (c == '(') {
stack.push(')');
} else if (c == '[') {
stack.push(']');
} else {
if (stack.isEmpty()) {
return false;
}
// 来到了右括号,就需要判断栈顶的括号和遇到的右括号是否一致
Character pop = stack.pop();
if (!pop.equals(c)) {
return false;
}
}
}
return stack.isEmpty();
}
}
题目:
代码:
public class BM45 {
public static void main(String[] args) {
BM45 demo = new BM45();
int[] arr = {2, 3, 4, 2, 6, 2, 5, 1};
demo.maxInWindows(arr, 3);
}
public ArrayList<Integer> maxInWindows(int[] num, int size) {
int length = num.length;
// 结果集
ArrayList<Integer> ans = new ArrayList<>(length - size + 1);
// base case
if (size <= 0 || size > length) {
return ans;
}
// 利用一个双端队列,维护滑动窗口
// 双端队列中存储的是数组元素的下标(单调队列是从大到小)
Deque<Integer> deque = new LinkedList<>();
// 初始化
for (int i = 0; i < size; i++) {
push(deque, num, i);
}
// 第一个元素结果
ans.add(num[deque.peekFirst()]);
// 开始队列弹出
for (int i = size; i < num.length; i++) {
// 判断是否需要将第一个元素弹出
if (deque.peekFirst() == i - size) {
deque.pollFirst();
}
push(deque, num, i);
ans.add(num[deque.peekFirst()]);
}
return ans;
}
// 加入元素下标到队列中
public void push(Deque<Integer> deque, int[] num, int index) {
if (deque.isEmpty()) {
deque.addLast(index);
} else {
while (!deque.isEmpty() && num[deque.peekLast()] <= num[index]) {
deque.pollLast();
}
deque.addLast(index);
}
}
}
题目:
代码:
public class BM46 {
public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
// 采用优先级队列
PriorityQueue<Integer> queue = new PriorityQueue<Integer>((a, b) -> {
return b - a;
});
// 结果集
ArrayList<Integer> ans = new ArrayList<>();
if (k <= 0 || k > input.length) {
return ans;
}
for (int i = 0; i < k; i++) {
queue.offer(input[i]);
}
for (int i = k; i < input.length; i++) {
queue.offer(input[i]);
queue.poll();
}
for (int i = 0; i < k; i++) {
ans.add(queue.poll());
}
return ans;
}
}
题目:
思路:
代码:
public class BM47 {
public int findKth(int[] a, int n, int K) {
// write code here
return findK(a, 0, n - 1, K);
}
// 找到第K个大的元素
public int findK(int[] arr, int left, int right, int K) {
if (left <= right) {
int index = partition(arr, left, right);
// condition
if (index == K - 1) {
return arr[index];
} else if (index < K - 1) {
return findK(arr, index + 1, right, K);
} else {
return findK(arr, left, index - 1, K);
}
}
return -1;
}
// 采用快速排序,每次partition都可以将数组中的元素分组,返回排序后基准值在数组中的下标
// 寻找第K大,就将数组按照从大到小的顺序排序
public int partition(int[] arr, int left, int right) {
// 基准值以数组中最左元素
int pivot = arr[left];
// 开始分组
while (left < right) {
while (left < right && arr[right] <= pivot) {
right--;
}
// 交换
arr[left] = arr[right];
while (left < right && arr[left] >= pivot) {
left++;
}
arr[right] = arr[left];
}
// 此时是left==right的情况
arr[left] = pivot;
return left;
}
}
题目:
思路:
代码:
public class BM48 {
// 维护一个优先级队列
// 小的优先级队列
PriorityQueue<Integer> small = new PriorityQueue<>();
// 大的优先级队列
PriorityQueue<Integer> big = new PriorityQueue<>((a, b) -> {
return b - a;
});
// 定义一个变量记录数据流中的元素个数
int size = 0;
public void Insert(Integer num) {
if (size % 2 == 0) {
// 如果数据流中的元素个数是偶数的话
// 将元素加入到大根堆中,并将大根堆的最后一个元素放入小根堆
big.add(num);
small.offer(big.poll());
} else {
// 如果数据流中的元素个数是奇数的话
small.offer(num);
big.offer(small.poll());
}
size++;
}
public Double GetMedian() {
if (size % 2 == 0) {
// 偶数
return (double) (small.peek() + big.peek()) / 2;
} else {
return (double) small.peek();
}
}
}
题目:
思路:
代码:
public class BM49 {
public int solve(String s) {
// write code here
// 消除字符串中的全部空格
s = s.replaceAll(" ", "");
char[] charArray = s.toCharArray();
// 栈结构
Stack<Integer> nums = new Stack<>();// 数栈
Stack<Character> operations = new Stack<>();// 操作符栈
// 首先给数栈中添加一个元素
nums.push(0);
// 开始遍历
for (int i = 0; i < charArray.length; i++) {
// 当前的char字符
char c = charArray[i];
// 判断条件
if ('(' == c) {
// 如果是这种括号,就直接加入到符号栈中
operations.push(c);
} else if (')' == c) {
// 如果是 这种括号,就需要进行计算
while (!operations.isEmpty()) {
if ('(' == operations.peek()) {
operations.pop();
break;
} else {
calculate(nums, operations);
}
}
} else {
// 要么是数字要么是“+ - *”的符号了
if (isNumber(c)) {
// 如果是数字,找到数字加入到集合中
int left = i;
int num = 0;
while (left < charArray.length && isNumber(charArray[left])) {
num = num * 10 + (charArray[left] - '0');
left++;
}
i = left - 1;
nums.push(num);
} else {
// 如果是符号
if (i > 0 && ('(' == charArray[i - 1] || '+' == charArray[i - 1] || '-' == charArray[i - 1])) {
nums.push(0);
}
// 只有当,当前的运算符优先级大于或等于符号栈的栈顶符号优先级时,才会运算
while (!operations.isEmpty() && operations.peek() != '(') {
// 运算
char peek = operations.peek();
if (map.get(peek) >= map.get(c)) {
calculate(nums, operations);
} else {
break;
}
}
operations.push(c);
}
}
}
// 最后计算
while (!operations.isEmpty()&&operations.peek() !='('){
calculate(nums,operations);
}
return nums.peek();
}
// 判断是否为数字
public boolean isNumber(char c) {
return Character.isDigit(c);
}
// 创建一个hashMap 存储操作符的优先级
Map<Character, Integer> map = new HashMap() {
{
put('+', 1);
put('-', 1);
put('*', 2);
}
};
// 操作数栈和符号栈,进行运算
public void calculate(Stack<Integer> nums, Stack<Character> operations) {
if (nums.size() < 2 || operations.isEmpty()) {
return;
}
int b = nums.pop();
int a = nums.pop();
char operation = operations.pop();
int ans;
if ('-' == operation) {
ans = a - b;
} else if ('+' == operation) {
ans = a + b;
} else {
ans = a * b;
}
nums.push(ans);
}
}
关于try
-catch
-finally
的知识点:
一旦在finally块中使用了return或throw语句,将会导致try块,catch块中的return,throw语句失效 。
关于类方法
的知识点:
类的方法,所谓类的方法就是指类中用static 修饰的方法(非static 为实例方法),比如main 方法,那么可以以main方法为例,可直接调用其他类方法,必须通过实例调用实例方法,this 关键字不是这么用的 。