今日刷题内容:
队列
前言
- 一个算法废材的刷题之路开更了, 更新每天刷题的题解内容
- 注重个人理解,看难度更新题目数量
- 题目来源于力扣
- 新开专栏,争取每日都能做出至少一题=v=
- 语言java、python、c\c++
一、今日题目
- 933. 最近的请求次数★☆☆☆☆
- 2073. 买票需要的时间★☆☆☆☆
- 641. 设计循环双端队列★★☆☆☆
- 1670. 设计前中后队列★★☆☆☆
二、解题思路
1. 933. 最近的请求次数★☆☆☆☆
并没有用队列的思想来解决本题
- 已知传入的t是严格递增的
- 只需一个数组用来维护之前输入的值
- 每次遍历从当前值向下找在[t-3000, t]之间的元素个数,相加即是答案
class RecentCounter {
int count = 0;
int[] temp;
public RecentCounter() {
temp = new int[10010];
}
public int ping(int t) {
temp[count++] = t;
int ret = 0;
for(int i = count - 1; i >= 0; i--){
if(temp[i] >= t - 3000 && temp[i] <= t){
ret++;
}else{
break;
}
}
return ret;
}
}
2. 2073. 买票需要的时间★☆☆☆☆
依旧是按照自己的想法来解题的
- 需求第k个顾客排队买到票所需的时间
- 当tickets[k] > 0时遍历数组即可
- 每次遍历如果当前元素大于0,将当前元素–,再将sum++
- 如果i = tickets的长度,再把i置为0即可
class Solution {
public int timeRequiredToBuy(int[] tickets, int k) {
int sum = 0;
int n = tickets.length;
int i = 0;
while(tickets[k] > 0){
if(tickets[i] >= 1){
tickets[i]--;
sum++;
}
i++;
if (i == n) i = 0;
}
return sum;
}
}
3. 641. 设计循环双端队列★★☆☆☆
- 可以用数组来实现,因为和第四题比较类似,可以参考第四题,就不写本题的题解了
class MyCircularDeque {
int[] list;
int front = 2500;
int last = front - 1;
int size;
public MyCircularDeque(int k) {
list = new int[5000];
size = k;
}
public int getSize(){
return front - last - 1;
}
public boolean insertFront(int value) {
if (getSize() == size){
return false;
}
list[front++] = value;
return true;
}
public boolean insertLast(int value) {
if (getSize() == size){
return false;
}
list[last--] = value;
return true;
}
public boolean deleteFront() {
if (getSize() == 0){
return false;
}
front--;
return true;
}
public boolean deleteLast() {
if (getSize() == 0){
return false;
}
last++;
return true;
}
public int getFront() {
if (getSize() == 0){
return -1;
}
return list[front-1];
}
public int getRear() {
if (getSize() == 0){
return -1;
}
return list[last+1];
}
public boolean isEmpty() {
return getSize() == 0;
}
public boolean isFull() {
return getSize() == size;
}
}
4.1670. 设计前中后队列★★☆☆☆
- 这题主要注意的是从中间插入和从中间取出
- 每次从中间插入的时候,位置都位于队首指针+队列长度/2的位置
- 每次从中间取出时,情况则不同(并没有用英雄哥的数学归纳法)
- 当队列元素为1或2时,都是取队首的第一个元素
- 当队列元素个数为奇数时,要取的元素位于队首指针 + 队列长度/2 +1的位置
- 当队列元素个数为偶数数时,要取的元素位于队首指针 + 队列长度/2的位置
- 取到元素后,将整个队首元素后移即可
class FrontMiddleBackQueue {
int[] list;
int front = 2500;
int last = front + 1;
public FrontMiddleBackQueue() {
list = new int[5000];
}
public int getSize(){
return last - front - 1;
}
public boolean isEmpty(){
return getSize() == 0;
}
public boolean isOdd(int num){
return num % 2 == 1;
}
public void pushFront(int val) {
list[front--] = val;
}
public void pushMiddle(int val) {
int idx = 0;
idx = front + getSize() / 2;
for(int i = front; i < idx; i++){
list[i] = list[i+1];
}
front--;
list[idx] = val;
}
public void pushBack(int val) {
list[last++] = val;
}
public int popFront() {
if (isEmpty()){
return -1;
}
return list[++front];
}
public int popMiddle() {
if (isEmpty()){
return -1;
}
if(getSize() == 1 || getSize() == 2){
return list[++front];
}
int idx = 0;
if ( isOdd(getSize()) ){
idx = front + getSize() / 2 + 1;
}else{
idx = front + getSize() / 2;
}
int temp = list[idx];
for(int i = idx; i > front; i--){
list[i] = list[i-1];
}
front++;
return temp;
}
public int popBack() {
if (isEmpty()){
return -1;
}
return list[--last];
}
}
|