堆/栈/队列/排序
BM42 用两个栈实现队列
import java.util.Stack;
public class Solution {
Stack<Integer> s1 = new Stack<Integer>();
Stack<Integer> s2 = new Stack<Integer>();
public void push(int node) {
s1.push(node);
}
public int pop() {
if(s2.isEmpty()){
while(!s1.isEmpty()) s2.push(s1.pop());
}
return s2.pop();
}
}
BM43 包含min函数的栈
import java.util.Stack;
public class Solution {
Stack<Integer> s1=new Stack<>();
Stack<Integer> s2=new Stack<>();
public void push(int node) {
s1.push(node);
if(s2.isEmpty()||s2.peek()>=node) s2.push(node);
}
public void pop() {
if(s1.pop().equals(s2.peek())) s2.pop();
}
public int top() {
return s1.peek();
}
public int min() {
return s2.peek();
}
}
BM44 有效括号序列
import java.util.*;
public class Solution {
public boolean isValid (String s) {
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='(') stack.push(')');
else if(s.charAt(i)=='[') stack.push(']');
else if(s.charAt(i)=='{') stack.push('}');
else if(stack.isEmpty() || s.charAt(i)!=stack.pop()) return false;
}
return stack.isEmpty();
}
}
BM45 滑动窗口的最大值
import java.util.*;
public class Solution {
ArrayList<Integer> res=new ArrayList<>();
public ArrayList<Integer> maxInWindows(int [] num, int k) {
if(num.length==0|| k==0) return res;
Deque<Integer> deque=new LinkedList<>();//双端队列
for(int i=0;i<k;i++){
while(!deque.isEmpty() && deque.peekLast()<num[i]) deque.removeLast();
deque.addLast(num[i]);
}
res.add(deque.peekFirst());
for(int i=k;i<num.length;i++){
if(num[i-k]==deque.peekFirst()) deque.removeFirst();
while(!deque.isEmpty() && deque.peekLast()<num[i]) deque.removeLast();
deque.addLast(num[i]);
res.add(deque.peekFirst());
}
return res;
}
}
BM46 最小的K个数
import java.util.ArrayList;
class Solution {
ArrayList<Integer> res=new ArrayList<>();
public ArrayList<Integer> GetLeastNumbers_Solution(int[] arr, int k) {
if(k>arr.length || k==0 || arr==null) return res;
quickSort(arr,k,0,arr.length-1);
return res;
}
private void quickSort(int[] arr,int k,int l,int r){
int i=l,j=r;
while(i<j){
while(i<j&&arr[j]>=arr[l])j--;
while(i<j&&arr[i]<=arr[l])i++;
swap(arr,i,j);
}
swap(arr,i,l);
if(i>k) quickSort(arr,k,l,i-1);
else if(i<k) quickSort(arr,k,i+1,r);
else{
for(int m=0;m<k;m++)
res.add(arr[m]);
}
}
private void swap(int[] arr,int i,int j){
if (i == j)return;
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
BM47 寻找第K大
import java.util.*;
public class Solution {
public int findKth(int[] nums,int n, int k) {
int tar=n-k;
int left=0,right=n-1;
while(true){
int index = partition(nums,left,right);
if(index < tar) left=index+1;
else if(index > tar) right=index-1;
else return nums[index];
}
}
public int partition(int[] nums,int l,int r){
int picked=(int)(Math.random()*(r-l+1))+l;
swap(nums,picked,l);
int j=l;
for(int i=l+1;i<=r;i++){
if(nums[i]<nums[l]){
j++;
swap(nums,j,i);
}
}
swap(nums,j,l);
return j;
}
public void swap(int[] nums,int a,int b){
int tmp=nums[a];
nums[a]=nums[b];
nums[b]=tmp;
}
}
BM48 数据流中的中位数
import java.util.PriorityQueue;
public class Solution {
PriorityQueue<Integer> A=new PriorityQueue<>();
PriorityQueue<Integer> B=new PriorityQueue<>((x,y)->(y-x));
public void Insert(Integer num) {
if(A.size()!=B.size()){
A.add(num);
B.add(A.poll());
}else{
B.add(num);
A.add(B.poll());
}
}
public Double GetMedian() {
return A.size()!=B.size()?A.peek()/1.0:(A.peek()+B.peek())/2.0;
}
}
BM49 表达式求值
import java.util.*;
public class Solution {
public int solve (String s) {
Stack<Integer> stack = new Stack<>();//初始化栈
int num= 0;//默认数字
char sign = '+';//默认的第一个数字前的运算符为 +
char[] arr = s.toCharArray();//字符串转化字符数组
for(int i = 0;i<s.length();i++){//对字符数组每个元素遍历
char c = arr[i];
if (c == ' ') continue;
if(c == '('){//是否为左括号
int j = i + 1;
int counterPar = 1;//默认是1对括号
while(counterPar > 0){//统计是否存在括号嵌套的情况
if(arr[j] == '(') counterPar++;
else if(arr[j] == ')')counterPar--;
//向后直到找到右括号
j++;
}
//遇到左括号递归求这个括号里面表达式的值
//就是求左括号 到 右括号 之间 表达式的 值,返回值为 number,下面接着进栈
num = solve(s.substring(i + 1,j - 1));
//下一次就要从 j 开始,因为后面还有一个 i ++;
i = j - 1;
}
if(Character.isDigit(c)) num = num * 10 + c - '0';//是否为数字,是数字就求完整的数字值,每次循环都进这个分支,直到出现运算符
if( ! Character.isDigit(c) || i == s.length() - 1){ //不是数字 或者 为最后一个字符
if(sign == '+') stack.push(num);//是 + 先把 数字 压栈,等会全部数字出栈之和即为所求
else if(sign == '-') stack.push( -1 * num);//是 - 压栈该数字的相反数
else if(sign == '*') stack.push(stack.pop() * num);//是 * ,弹栈算出结果,在压栈
else if(sign == '/') stack.push(stack.pop() / num);//是 / ,弹栈算出结果,在压栈
num = 0; //每次结束,数字恢复默认值
// 遇到运算符时或者到表达式末尾时,就去计算上一个运算符并把计算结果push进栈,然后保存新的运算符
//运算符为 当前压栈数字 前面近邻的那个
sign = c;
//如果是负数 在 表达式的最前面 ,会先压栈 +0,然后在记录当前 负号,开始接下来的数字
}
}
int sum = 0; //结果
while(!stack.isEmpty()){
sum += stack.pop();
}
return sum;
}
}
BM20 数组中的逆序对
public class Solution {
int[] arr,assist;
public int InversePairs(int [] arr) {
this.arr=arr;
assist=new int[arr.length];
return merge(0,arr.length-1);
}
private int merge(int l,int r){
if(l>=r) return 0;
int m=(l+r)/2;
int res=merge(l,m)+merge(m+1,r);
for(int k=l;k<=r;k++){
assist[k]=arr[k];
}
int i=l,j=m+1;
for(int k=l;k<=r;k++){
if(i==m+1){
arr[k]=assist[j++];
}else if(j==r+1 || assist[i]<=assist[j]){
arr[k]=assist[i++];
}else{
arr[k]=assist[j++];
res=(res+m-i+1)%1000000007;
}
}
return res;
}
}