代码随想录 刷题攻略
电信保温杯笔记——代码随想录 刷题攻略
讲义地址
讲义地址
leetcode地址
class MyQueue {
Stack stack = new Stack();
public MyQueue() {
}
public void push(int x) {
Stack temp = new Stack();
while (!stack.empty()){
temp.push(stack.pop());
}
stack.push(x);
while (!temp.empty()){
stack.push(temp.pop());
}
}
public int pop() {
return (int) stack.pop();
}
public int peek() {
return (int) stack.peek();
}
public boolean empty() {
return stack.empty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
讲义地址
leetcode地址
class MyStack {
Queue queue = new LinkedList();
public MyStack() {
}
public void push(int x) {
Queue temp = new LinkedList();
while (!queue.isEmpty()){
temp.add(queue.poll());
}
queue.add(x);
while (!temp.isEmpty()){
queue.add(temp.poll());
}
}
public int pop() {
return (int) queue.poll();
}
public int top() {
return (int) queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
讲义地址
leetcode地址
有三种不匹配的情况
class Solution {
public boolean isValid(String s) {
int len = s.length();
if (len % 2 == 1){
return false;
}
HashMap<Character, Character> map = new HashMap<>();
map.put(']', '[');
map.put('}', '{');
map.put(')', '(');
Stack stack = new Stack();
for (int i = 0; i < len; i++) {
char temp = s.charAt(i);
if(!stack.empty() && map.get(temp) == stack.peek()){
stack.pop();
}else{
stack.push(temp);
}
}
return stack.empty();
}
}
讲义地址
leetcode地址
class Solution {
public String removeDuplicates(String s) {
int len = s.length();
Stack<Character> stack = new Stack();
for (int i = 0; i < len; i++) {
char temp = s.charAt(i);
if (!stack.empty() && temp == stack.peek()){
stack.pop();
}else{
stack.push(temp);
}
}
String res = "";
while (!stack.empty()){
res = stack.pop() + res;
}
return res;
}
}
class Solution {
public String removeDuplicates(String s) {
StringBuffer res = new StringBuffer();
int top = -1;
int len = s.length();
for (int i = 0; i < len; i++) {
char temp = s.charAt(i);
if (top >=0 && temp == res.charAt(top)){
res.deleteCharAt(top);
top--;
}else{
res.append(temp);
top++;
}
}
return res.toString();
}
}
讲义地址
leetcode地址
class Solution {
public int evalRPN(String[] tokens) {
int len = tokens.length;
Set<String> set = new HashSet<>();
set.add("+");
set.add("-");
set.add("*");
set.add("/");
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < len; i++) {
String temp = tokens[i];
if (!stack.empty() && set.contains(temp)){
int n = stack.pop();
int m = stack.pop();
stack.push(calculate(m, n, temp));
}else {
stack.push(Integer.valueOf(temp));
}
}
return stack.pop();
}
public int calculate(int m, int n, String s){
int res = 0;
if ("+".equals(s)){
res = m + n;
}
if ("-".equals(s)){
res = m - n;
}
if ("*".equals(s)){
res = m * n;
}
if ("/".equals(s)){
res = m / n;
}
return res;
}
}
讲义地址
leetcode地址
//解法一
//自定义数组
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int len = nums.length;
if (len == 1) {
return nums;
}
//存放结果元素的数组
int[] res = new int[len - k + 1];
//自定义队列
MyQueue myQueue = new MyQueue();
//先将前k的元素放入队列
for (int i = 0; i < k; i++) {
myQueue.add(nums[i]);
}
res[0] = myQueue.peek();
int index = 1;
for (int i = k; i < len; i++) {
//滑动窗口移除最前面的元素,移除是判断该元素是否放入队列
myQueue.poll(nums[i - k]);
//滑动窗口加入最后面的元素
myQueue.add(nums[i]);
//记录对应的最大值
res[index] = myQueue.peek();
index++;
}
return res;
}
class MyQueue {
Deque<Integer> deque = new LinkedList<>();
//弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
//同时判断队列当前是否为空
void poll(int val) {
if (!deque.isEmpty() && val == deque.peek()) {
deque.poll();
}
}
//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
//保证队列元素单调递减
//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
void add(int val) {
while (!deque.isEmpty() && val > deque.getLast()) {
deque.removeLast();
}
deque.add(val);
}
//队列队顶元素始终为最大值
int peek() {
return deque.peek();
}
}
}
//解法二
//利用双端队列手动实现单调队列
/**
* 用一个单调队列来存储对应的下标,每当窗口滑动的时候,直接取队列的头部指针对应的值放入结果集即可
* 单调队列类似 (tail -->) 3 --> 2 --> 1 --> 0 (--> head) (右边为头结点,元素存的是下标)
*/
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;
}
}
讲义地址
leetcode地址
class Solution {
public int[] topKFrequent(int[] nums, int k) {
int len = nums.length;
int[] res = new int[k];
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < len; i++) {
int temp = nums[i];
map.put(temp, map.getOrDefault(temp, 0) + 1);
}
// 根据map的value值正序排,相当于一个小顶堆
Set<Map.Entry<Integer, Integer>> set = map.entrySet();
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> t1) {
return o1.getValue() - t1.getValue();
}
});
for (Map.Entry<Integer, Integer> entry : set) {
queue.add(entry);
if (queue.size() > k) {
// 频率小的弹出
queue.poll();
}
}
for (int i = k - 1; i >= 0; i--) {
res[i] = queue.poll().getKey();
}
return res;
}
}
讲义地址