最近数据结构出期末成绩了,心血来潮上洛谷做一下数据结构题
洛谷P1160 队列安排
https://www.luogu.com.cn/problem/P1160
题目
分析
啊这,太恶心了,用LinkedList的话查找不好找,用ArrayList的话插入删除又不爽,所以我决定用
数组+双链表的方式
仔细一想,方案完全可行,用个指针数组指向每个节点(一直都维护head指针),最后遍历链表就是答案了
代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class Main {
static class node{
int data;//用来存编号
node prev;//指向前面
node next;//指向后面
public node(int data) {
this.data = data;
}
public node() {
}
}
static int n,m,head=1;//head为头节点的编号
static node arr[];//指针数组
public static void main(String[] args) throws IOException {
n=nextInt();
arr=new node[n+1];
for (int i = 2; i <=n; i++)
insert(i, nextInt(), nextInt());
m=nextInt();
for (int i = 0; i < m; i++)
delete(nextInt());
PrintArr();
}
// (2,1,0)将2号插入到1号的左边
static void insert(int srcPos,int targerPos,int direction) {
//顺便初始化节点
if(arr[srcPos]==null)
arr[srcPos]=new node(srcPos);
if(arr[targerPos]==null)
arr[targerPos]=new node(targerPos);
node src=arr[srcPos],tar=arr[targerPos];
if(direction==0) {//left
if(tar.prev!=null) {
src.prev=tar.prev;
tar.prev.next=src;
}
tar.prev=src;
src.next=tar;
if(targerPos==head)
head=srcPos;
}else {//right
if(tar.next!=null) {
src.next=tar.next;
tar.next.prev=src;
}
tar.next=src;
src.prev=tar;
}
}
static void delete(int targerPos) {
node tar=arr[targerPos];
if(tar==null)
return;
node front=tar.prev,behind=tar.next;
if(front!=null&&behind!=null) {//tar左右都有节点
front.next=behind;
behind.prev=front;
}else if(front==null) {//tar是最左边节点
head=behind.data;
behind.prev=null;
}else {//tar是最右边节点
front.next=null;
}
arr[targerPos]=null;
}
static void PrintArr() {
node pMove=arr[head];
StringBuilder sb=new StringBuilder(n*2);//尽量避免扩容
while(pMove!=null) {
sb.append(pMove.data+" ");
pMove=pMove.next;
}
System.out.println(sb);
}
static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st=new StreamTokenizer(in);
static double nextDouble() throws IOException{
st.nextToken();
return st.nval;
}
static int nextInt() throws IOException {
return (int)nextDouble();
}
}
撒花
感想
典型的空间换时间,结合数组的查找和链表的插入删除,没有多余的时间复杂度,避免了扩容、移动元素、顺序查找等感人操作
我不知道能不能结合用指针数组分别去指向LinkedList的每个节点,所以我直接手打,如果有更简单的写法再回来更新