//创建一个栈用来存最终结果
Stack<Character> stack = new Stack<>();
/**
* 316. 去除重复字母(https://leetcode-cn.com/problems/remove-duplicate-letters)
* 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
* /
public String removeDuplicateLetters(String s) {
//创建一个栈用来存最终结果
Stack<Character> stack = new Stack<>();
//用来存栈中已经存在的数据,用于判断一个数据,栈中是否已经存在不需要压栈
HashSet<Character> exist = new HashSet<>();
//存每个字母最后一次出现的位置,如果是最后一次出现,则不可再变动
HashMap<Character, Integer> lastOccur = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
lastOccur.put(s.charAt(i),i);
}
for (int i = 0; i < s.length(); i++) {
//如果栈中没有则进行处理,栈中有这不需要处理直接丢弃
if(!exist.contains(s.charAt(i))){
//判断已在栈中的数据是否需要弹栈
//栈中有数据,栈顶数据大于要进入的数据,要进入的数据最后一次出现的位置大于改位置(就是这个位置不是字母最后出现的位置)
while (stack.size()>0 && stack.peek()>s.charAt(i) && lastOccur.get(stack.peek())>i){
Character pop = stack.pop();
exist.remove(pop);
}
stack.push(s.charAt(i));
exist.add(s.charAt(i));
}
}
//返回值为string,将stack中的数据放入stringBuilder中
StringBuilder stringBuilder = new StringBuilder();
for (Character character : stack) {
stringBuilder.append(character.charValue());
}
return stringBuilder.toString();
}
2、堆(优先队列(Priority Queue)来实现大顶堆)
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1; //从大到小
}
});
/**
* nitialCapacity – the initial capacity for this priority queue
* comparator – the comparator that will be used to order this priority queue. If null, the natural ordering of the elements will be used.
*/
public PriorityQueue(int initialCapacity,Comparator<? super E> comparator)
3、对列(双向对列Deque)
ArrayDeque<Integer> deque = new ArrayDeque<>();
/**
* 239. 滑动窗口最大值 (https://leetcode-cn.com/problems/sliding-window-maximum/)
* 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
*
* 返回 滑动窗口中的最大值 。
* /
//方法一、双向对列
public int[] maxSlidingWindow(int[] nums, int k) {
if (k == 1) return nums;
int[] result = new int[nums.length - k + 1];
ArrayDeque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < k; i++) {
while (!deque.isEmpty() && nums[i]>nums[deque.getLast()]){
deque.removeLast();
}
deque.add(i);
}
result[0]=nums[deque.getFirst()];
for (int i = k; i < nums.length; i++) {
// 如:724,7吗,没法被删除 !deque.isEmpty() && nums[i]>nums[deque.getFirst()]
//将上一个最大值删掉
if(!deque.isEmpty() && deque.getFirst()==i-k){
deque.removeFirst();
}
while (!deque.isEmpty() && nums[i]>nums[deque.getLast()]){
deque.removeLast();
}
deque.add(i);
result[i-k+1]=nums[deque.getFirst()];
}
return result;
}
//大顶堆
public int[] maxSlidingWindow2(int[] nums, int k) {
int[] result = new int[ nums.length-k+1];
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (int i = 0; i <k; i++) {
maxHeap.add(nums[i]);
}
result[0]=maxHeap.peek();
for (int i = 1; i < nums.length-k+1 ; i++) {
maxHeap.remove(nums[i-1]);
maxHeap.add(nums[i+k-1]);
result[i]=maxHeap.peek();
}
return result;
}