队列有五种基本操作,插入队尾、取出队首、删除队首、队列大小、清空队列。
现在让你模拟一个队列的操作,具体格式参考输入。
注意本题有多组输入。
数据范围: 操作数满足
,读入的数都满足 
进阶:空间复杂度
,所有操作的时间复杂度都满足 %20%5C)
进阶:空间复杂度
第一行输入一个整数T,表示接下来有T组测试数据。
对于每组测试数据:
第一行输入一个整数Q,表示有Q次操作。
接下来Q行,每行输入一种队列操作方式,具体格式如下:
初始状态下队列为空。
插入队尾:PUSH X
取出队首:TOP//仅仅是看一下队首元素,不要把队首元素删除
删除队首:POP
队列大小:SIZE清空队列:CLEAR1<=T<=1001<=Q,x<=1000保证操作为以上5种的任意一种。
对于每组测试数据:
如果操作为“取出队首”,输出队首元素,如果无法取出,输出“-1”
如果操作为“删除队首”,如果无法删除,输出“-1”
如果操作为“队列大小”,输出队列大小
其他操作无需输出
2 7 PUSH 1 PUSH 2 TOP POP TOP POP POP 5 PUSH 1 PUSH 2 SIZE POP SIZE
1 2 -1 2 1
运用基础的数组模拟队列,将队列以及对队列的操作均放在一个类里面,代码略显得多,但是并不复杂,也有很多值得优化的地方。 仅就解题来说,要注意的是,队列要设置成环形队列,防止出现push很多次以后再pop很多次以后,不能再操作队列了,环形队列可以避免这一点。注意环形队列的几个要点; 1、环形“有尾巴”:设置rear指向最后一个元素的下一个位置,front指向第一个元素,初始值均为0,队列长度为:(rear-front+maxsize)%maxsize; 2、队列满的条件是:(rear+1)%maxsize=front;3、队列为空的条件是:rear==front;import java.util.*; public class Main { public static void main(String[] args) { //输入数组和n Scanner sc = new Scanner(System.in); String line = sc.nextLine(); int T = Integer.parseInt(line); int Max = 1000;//? ArrayList<Integer> res = new ArrayList<>(); for (int i = 0; i < T; i++) {//T组测试数据 Queue queue = new Queue(Max);//一个队列反复操作 则需要环形队列 String line1 = sc.nextLine(); int Q = Integer.parseInt(line1);//Q次操作 for (int j = 0; j < Q; j++) {//Q次操作 把需要打印的操作的结果存放到一个数组res中 最后轮流换行打印输出 String s = sc.nextLine(); String[] s1 = s.split(" "); switch (s1[0]) { case "PUSH": //插入队尾元素无返回 queue.push(s1[1]); break; } switch (s1[0]) { case "SIZE": //队列大小 res.add(queue.size()); break; } switch (s1[0]) { case "TOP": //队列首元素查询 res.add(queue.top()); break; } switch (s1[0]) { case "POP": //删除队首元素 if(queue.pop()!=null){ res.add(queue.pop()); } break; } switch (s1[0]) { case "CLEAR": queue.clear();//清空队列 无返回 break; } } } for (int i = 0; i < res.size(); i++) { System.out.println(res.get(i)); } } } class Queue { private int Maxsize; private int front;//指向队首 private int rear;//指向队尾元素的后一个位置 初值为0 private int[] arr;//存放数据 public Queue(int maxsize) { Maxsize = maxsize; arr =new int[Maxsize];//数组不初始化,就是null 也无索引也无0 front = 0; rear = 0; } public void push(String s) { int x = Integer.parseInt(s); arr[rear] = x; rear = (rear + 1) % Maxsize; } public Integer size() { return (rear - front + Maxsize) % Maxsize; } public Integer top() { if (rear == front) {//为空无法取出 return -1; } return arr[front]; } public Integer pop() { if (rear == front) { //为空无法删除 return -1; } front = (front + 1) % Maxsize;//注意是加1取模 不改变arr 这就算删除队列一个元素了 return null; } public void clear() { rear=front;//清空队列?? } }
class Queue { constructor(n){ this.maxsize=n //数组最大容量 this.arr = new Array(n)//用于存数据的数组,模拟队列 this.front = this.rear = 0//初始化下标值,指向队列头部 } push(n){ this.arr[this.rear]=n this.rear = (this.rear+1)%this.maxsize } top(){ if(this.rear==this.front){//为空无法取出 return -1 } return this.arr[this.front] } pop(){ if(this.rear==this.front){//为空无法删除 return -1 } this.front = (this.front+1)%this.maxsize return null } size(){ return (this.rear-this.front+this.maxsize)%this.maxsize } clear(){ this.rear = this.front } } var T = parseInt(readline()) for(var i=0;i<T;i++){ let queue = new Queue(1000) var Q = parseInt(readline()) for(var j=0;j<Q;j++){ var lines = readline().split(" ") switch (lines[0]){ case "PUSH": queue.push(lines[1]) break } switch (lines[0]){ case "TOP": console.log(queue.top()) break } switch (lines[0]){ case "POP": if(queue.pop()!==null){ console.log(queue.pop()) } break } switch (lines[0]){ case "SIZE": console.log(queue.size()) break } switch (lines[0]){ case "CLEAR": queue.clear() break } } }
T=int(input()) for i in range(T): #有T组测试数据 Q=int(input()) #改组测试数据有Q次操作 q=[] for j in range(Q): s = input().strip().split() if len(s)==2: #入队操作 q.append(s[1]) else: #其他操作 if s[0]=='TOP': #查看队首 if len(q)==0:print(-1) else:print(q[0]) elif s[0]=='SIZE': print(len(q)) elif s[0]=='POP': #出队 if len(q)==0:print(-1) else:del q[0] else: #clear清空操作 while len(q)!=0:q.pop()
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Queue; import java.util.LinkedList; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int T = Integer.parseInt(br.readLine().trim()); while(T -- > 0){ int n = Integer.parseInt(br.readLine().trim()); Queue<Integer> queue = new LinkedList<>(); for(int i = 0; i < n; i++){ String command = br.readLine(); if(command.startsWith("PUSH")){ String[] params = command.split(" "); int elem = Integer.parseInt(params[1]); queue.offer(elem); }else if(command.equals("TOP")){ if(queue.isEmpty()) System.out.println(-1); else System.out.println(queue.peek()); }else if(command.equals("POP")){ if(queue.isEmpty()) System.out.println(-1); else queue.poll(); }else if(command.equals("SIZE")){ System.out.println(queue.size()); }else if(command.equals("CLEAR")) queue.clear(); } } } }
#include <bits/stdc++.h> #define INF 0x3f3f3f3f //#define mod 998244353 #define mod 1000000007 #define ll long long using namespace std; const int N=1e6+5; const double ex=1e-8; int n,m,k; int a[N]; void solve(){ int head=0,en=0; string s; cin>>n; while(n--){ cin>>s; if(s=="PUSH"){ cin>>m; a[en++]=m; } else if(s=="TOP"){ if(head==en)cout<<-1<<'\n'; else cout<<a[head]<<'\n'; } else if(s=="POP"){ if(head==en)cout<<-1<<'\n'; else head++; } else if(s=="SIZE"){ cout<<en-head<<'\n'; } else{ en=head; } } } int main() { ios_base::sync_with_stdio(false); cin.tie(0);cout.tie(0); //cout<<fixed<<setprecision(10); int t; cin>>t; while(t--){ solve(); } return 0; }
使用数组模拟,维护一个front
和 一个rear
指针
#include <iostream> using namespace std; const int MAX = 1e5 + 5; int arr[MAX]; void solve() { int Q; cin >> Q; int rear = -1, front = -1; string ops; int val; while (Q--) { cin >> ops; if (ops == "PUSH") { cin >> val; arr[++rear] = val; } else if (ops == "POP") { if (front == rear) cout << "-1" << endl; else front++; } else if (ops == "TOP") { if (front == rear) cout << "-1" << endl; else cout << arr[front + 1] << endl; } else if (ops == "SIZE") { cout << rear - front << endl; } else { front = rear = -1; } } } int main() { int T; cin >> T; while (T--) { solve(); } }
基于链表实现:
#include <iostream> #include <string> #include <memory> using namespace std; struct ListNode { int value_; unique_ptr next_; explicit ListNode(int x) : value_{x}, next_{nullptr} {} }; class LinkedListQueue { private: unique_ptr front_; ListNode *rear_ {nullptr}; int queue_size_ {0}; public: LinkedListQueue () = default; LinkedListQueue(const LinkedListQueue&) = delete; LinkedListQueue& operator=(const LinkedListQueue&) = delete; // 获取长度 [[nodiscard]] int get_size() const { return queue_size_; } // 判断是否为空 [[nodiscard]] bool is_empty() const { return queue_size_ == 0; } // 入队(插入队尾):在尾节点后面添加num节点 void push(int num) { // 新建一个num节点 auto node = make_unique(num); // 当队列为空时,将头、尾节点都指向num节点 if(is_empty()) { rear_ = node.get(); // 将node的原始指针保存至rear_ front_ = std::move(node); // 转移所有权到front_ } else // 若队列不为空,将该节点添加至尾节点之后 { rear_->next_ = std::move(node); // 将当前尾节点的下一个节点指向num节点 rear_ = rear_->next_.get(); // 更新尾节点为num节点 } queue_size_++; } // 取出队首(仅查看队首元素) [[nodiscard]] int top() const { // 如果队列为空,直接返回-1 if(is_empty()) { return -1; } else // 否则返回队首元素 { return front_->value_; } } // 删除队首:将队首节点删除并返回删除的元素 int pop() { // 如果当前队列为空,则无法删除,输出-1 if(is_empty()) { return -1; } // 获取队首元素 int num = front_->value_; // 如果队首节点等于队尾节点,表明这是最后一个节点 if(front_.get() == rear_) { rear_ = nullptr; // 需要手动将队尾节点置空 } // 让队首节点指向下一个节点 front_ = std::move(front_->next_);// unique_ptr会自动删除旧节点 queue_size_--; return num; } // 清空队列 void clear() { front_ = nullptr; rear_ = nullptr; queue_size_ = 0; } }; int main() { int n; cin >> n; while(n--) { int q; cin >> q; LinkedListQueue queue; string manipulation; while(q--) { cin >> manipulation; if(manipulation == "PUSH") { int x; cin >> x; queue.push(x); } else if (manipulation == "TOP") { cout << queue.top() << endl; } else if (manipulation == "POP") { int res = queue.pop(); if(res == -1) { cout << res << endl; } } else if (manipulation == "SIZE") { cout << queue.get_size() << endl; } else if (manipulation == "CLEAR") { queue.clear(); } } } return 0; }
using System; using System.Collections.Generic; public class Program { public static void Main() { Queue<int> list = new Queue<int>(); int T = int.Parse(Console.ReadLine().Trim()); while(T>0) { T--; int Q=int.Parse( Console.ReadLine()); list.Clear(); while(Q>0) { Q--; string[] instruction=Console.ReadLine().Trim().Split(' '); switch(instruction[0]) { case "PUSH": { list.Enqueue(int.Parse(instruction[1])); break; } case "POP": { if (list.Count != 0) list.Dequeue(); else Console.WriteLine(-1); break; } case "TOP": { if (list.Count != 0) Console.WriteLine(list.Peek()); else Console.WriteLine(-1); break; } case "SIZE": { Console.WriteLine(list.Count); break; } case "CLEAR": { list.Clear(); break; } default:break; } } } } }
group = int(input()) while group > 0: group -= 1 number = int(input()) l = [] size = 0 while number > 0: number -= 1 command = input() if 'PUSH' in command: number0 = command.replace('PUSH ', '') number0 = int(number0) l.append(number0) size += 1 continue if 'TOP' in command: if size > 0: print(l[0]) else: print(-1) continue if 'POP' in command: if size > 0: size -= 1 del l[0] else: print(-1) continue if 'SIZE' == command: print(size) continue if 'CLEAR' == command: l = [] size = 0 continue
#include<bits/stdc++.h> using namespace std; void solve() { int k; cin >> k; deque<int> q; for(int j = 0; j< k;j++) { string ming_li; cin >> ming_li; if( ming_li == "PUSH") { int num; cin >> num; q.push_back(num); } else if( ming_li == "TOP") { if(q.empty()) { cout << -1 <<'\n'; continue; } cout << q.front() <<'\n'; } else if( ming_li == "POP") { if(q.empty()) cout << -1<<'\n'; q.pop_front(); } else if( ming_li == "SIZE") { cout << q.size() <<'\n'; } else if( ming_li == "CLEAR") { q.clear(); } } } int main() { ios_base::sync_with_stdio(false); cin.tie(0);cout.tie(0); int t; cin>>t; while(t--){ solve(); } return 0; }
这么写为什么是错误的,明明案例都是通过的,是因为使用了API吗。。。。。。
a = input(''); for i = 1:a b= input(''); str = {}; for ii = 1:b caozuo = strsplit(input('','s')); if length(caozuo)==2 str = [str,caozuo{2}]; else caozuo = caozuo{1}; if strcmp(caozuo,'TOP') if length(str) ~= 0;disp((str{1,1})); else disp(-1);end elseif strcmp(caozuo,'POP') if length(str) ~= 0;str(1)=[]; else disp(-1);end elseif strcmp(caozuo,'SIZE') disp(length(str)) elseif strcmp(caozuo,'CLEAR') str ={}; end end end end 哪位大神看看,总说我格式不对
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int times = sc.nextInt(); sc.nextLine(); while (times > 0) { MyQueue que = new MyQueue(); int n = sc.nextInt(); sc.nextLine(); for (int i = 0; i < n; i++) { String s = sc.nextLine(); if(s.startsWith("PUSH")){ String[] strs = s.split("\\s+"); int val = Integer.parseInt(strs[1]); que.push(val); }else{ switch (s){ case "TOP": if (que.size()==0){ System.out.println(-1); }else{ System.out.println(que.getHead()); } break; case "SIZE": System.out.println(que.size()); break; case "POP": if(que.size()==0){ System.out.println(-1); }else{ que.deque(); } break; case "CLEAR": que = new MyQueue(); break; default: break; } } } times--; } } static class MyQueue { public Node head; public Node tail; public int size; public MyQueue() { size = 0; head = new Node(); tail = head; } public void push(int val) { //入队使用尾插法 Node cur = new Node(val); cur.next = tail.next; tail.next = cur; tail = cur; size++; } public int deque() { //由于链表的特性,删除只能在头部删除 //用head保存头节点 if (size == 0) { return -1; } else { int x = head.next.val; head.next = head.next.next; size--; //关键性语句,如果队列中数据量为0 //要回归到初始状态,防止head和tail的指向会出现错误 if(size == 0){ head = new Node(); tail = head; } return x; } } public boolean isEmpty() { return size == 0; } public int size() { return size; } public int getHead() { if (size == 0) { return -1; } else { return head.next.val; } } } static class Node { int val; Node next; public Node(int val){ this.val = val; } public Node(){ } } }