洛谷P1160 队列安排——java手撸双链表

最近数据结构出期末成绩了,心血来潮上洛谷做一下数据结构题

洛谷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的每个节点,所以我直接手打,如果有更简单的写法再回来更新

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值