首页 > 编程语言 >【华为OD-E卷-最小调整顺序次数、特异性双端队列 100分(python、java、c++、js、c)】

【华为OD-E卷-最小调整顺序次数、特异性双端队列 100分(python、java、c++、js、c)】

时间:2024-12-25 15:32:16浏览次数:6  
标签:head java 队列 双端 remove js 命令 add 排序

【华为OD-E卷-最小调整顺序次数、特异性双端队列 100分(python、java、c++、js、c)】

题目

有一个特异性的双端队列,该队列可以从头部或尾部添加数据,但是只能从头部移出数据。
小A依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添加数据(可能从头部添加、也可能从尾部添加),依次添加1到n;n个指令是移出数据。
现在要求移除数据的顺序为1到n。
为了满足最后输出的要求,小A可以在任何时候调整队列中数据的顺序。
请问 小A 最少需要调整几次才能够满足移除数据的顺序正好是1到n;

输入描述

  • 第一行一个数据n,表示数据的范围。

接下来的2n行,其中有n行为添加数据,指令为:

“​head add x” 表示从头部添加数据 x,​"​tail add x" 表示从尾部添加数据x, 另外 n 行为移出数据指令,指令为:“remove” 的形式,表示移出1个数据;

1 ≤ n ≤ 3 * 10^5。

所有的数据均合法。

输出描述

  • 一个整数,表示 小A 要调整的最小次数。

用例

用例一:
输入:
5
head add 1
tail add 2
remove
head add 3
tail add 4
head add 5
remove
remove
remove
remove
输出:
1

python解法

  • 解题思路:
  • 任务目标:

处理一系列命令(add head, add tail, remove)对一个队列进行操作。
每次执行remove命令时,确保队列头部元素为指定的值current_remove,否则需要调整队列以满足条件。
统计所有remove命令中,为调整队列顺序而进行的排序操作次数。
实现逻辑:

使用一个列表模拟队列。
遍历命令:
对于add head和add tail命令,将元素插入队列的头部或尾部。
对于remove命令:
如果队列头部的元素与current_remove匹配,则直接移除。
否则,对队列进行排序,移除排序后的第一个元素,并记录一次调整操作。
最终返回调整次数。

def process_commands(cmds, n):
    # 队列初始化
    queue = []
    current_remove = 1  # 当前需要移除的目标值
    adjustments = 0     # 调整次数统计

    for cmd in cmds:
        # 处理当前命令
        handle_command(cmd, queue, current_remove)
        if cmd.startswith("remove"):
            # 对队列进行调整
            adjustments += adjust_queue(queue, current_remove)
            current_remove += 1  # 更新需要移除的目标值

    return adjustments

def handle_command(cmd, queue, current_remove):
    # 根据命令类型操作队列
    if "add" in cmd:
        _, _, x = cmd.split()  # 提取要添加的值
        if "head" in cmd:
            queue.insert(0, int(x))  # 添加到队列头部
        else:
            queue.append(int(x))     # 添加到队列尾部

def adjust_queue(queue, current_remove):
    # 检查队列头部是否为目标值
    if queue[0] == current_remove:
        queue.pop(0)  # 如果匹配,直接移除头部
        return 0      # 无需调整,返回 0
    else:
        queue.sort()  # 否则排序队列
        queue.pop(0)  # 移除排序后的第一个元素
        return 1      # 记录一次调整操作

# 输入获取
n = int(input())  # 命令对数
cmds = [input() for i in range(2 * n)]  # 获取所有命令

# 输出结果
print(process_commands(cmds, n))

java解法

  • 解题思路
  • 任务目标:

处理一系列命令(head add、tail add、remove)对队列进行操作。
每次执行remove命令时,如果队列未排序(head add会导致队列无序),需要对队列进行排序,并统计排序次数。
最终输出所有remove命令中,因排序操作产生的调整次数。
核心逻辑:

使用一个变量queueSize记录队列的大小。
使用布尔变量sorted标记队列是否处于有序状态:
head add操作可能破坏有序状态,将sorted设为false。
如果在执行remove时队列无序,则需要排序(adjustments计数加1),并恢复有序状态。
遍历命令列表,依次处理队列的增删操作,并更新状态和调整计数。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int len = Integer.parseInt(in.nextLine());  // 读取命令对数
        int total = len * 2;  // 总命令数为命令对数的两倍

        String[] cmds = new String[total];
        int j = 0;
        while (j < total) {
            cmds[j] = in.nextLine();  // 读取所有命令
            j++;
        }

        System.out.println(calculateAdjustments(cmds));  // 计算并输出调整次数
    }

    public static int calculateAdjustments(String[] cmds) {
        int queueSize = 0;      // 当前队列的大小
        boolean sorted = true; // 标记队列是否处于有序状态
        int adjustments = 0;    // 记录排序操作的次数
        int i = 0;

        while (i < cmds.length) {
            String cmd = cmds[i];
            if (cmd.startsWith("head add")) {
                // `head add` 操作可能破坏队列的有序状态
                if (queueSize > 0 && sorted) sorted = false;
                queueSize++;  // 队列大小加1
            } else if (cmd.startsWith("tail add")) {
                // `tail add` 操作不会破坏队列的有序状态
                queueSize++;  // 队列大小加1
            } else {  // 处理 `remove` 操作
                if (queueSize == 0) {  // 如果队列为空,跳过当前命令
                    i++;
                    continue;
                }
                if (!sorted) {  // 如果队列无序,需要排序
                    adjustments++;  // 增加调整次数
                    sorted = true;  // 恢复有序状态
                }
                queueSize--;  // 移除队列的一个元素
            }
            i++;
        }

        return adjustments;  // 返回总调整次数
    }
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 目标:

处理一系列命令(head add、tail add、remove)操作一个堆栈。
如果命令是head add,可能导致堆栈的顺序被破坏,需要在执行remove命令时进行排序以恢复顺序。
统计排序操作的次数(即需要恢复顺序的操作次数)。
实现逻辑:

使用stackSize记录当前堆栈的大小。
使用needSort标记堆栈是否需要排序:
head add会导致无序,将needSort设为true。
tail add不会影响顺序。
在remove时,如果needSort为true,需要排序(增加排序计数并重置needSort)。
遍历命令数组,根据命令类型更新堆栈状态和排序计数。
输入输出:

输入:第一行为命令对数n,接下来是2 * n条命令。
输出:所有remove命令中因排序产生的调整次数。

const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

let commands = [];
let numOps = 0;

rl.on("line", (line) => {
    commands.push(line); // 读取输入
    if (commands.length === 1) {
        numOps = parseInt(commands[0]); // 第一行表示命令对数
    } else if (commands.length === 1 + 2 * numOps) {
        commands.shift(); // 移除第一行命令对数
        console.log(processCommands(commands)); // 处理命令并输出结果
        commands = [];
    }
});

function processCommands(cmds) {
    let stackSize = 0;   // 当前堆栈的大小
    let needSort = false; // 是否需要排序
    let operations = 0;  // 排序操作次数统计

    cmds.forEach((cmd) => {
        if (cmd.startsWith("head add")) {
            // 如果是 `head add`,可能导致堆栈无序
            if (stackSize > 0) needSort = true; // 如果堆栈非空,标记需要排序
            stackSize++; // 增加堆栈大小
        } else if (cmd.startsWith("tail add")) {
            // 如果是 `tail add`,只增加堆栈大小,不影响顺序
            stackSize++;
        } else {
            // 如果是 `remove` 操作
            if (stackSize === 0) return; // 堆栈为空,跳过此命令

            if (needSort) {
                // 如果需要排序,增加排序操作计数
                operations++;
                needSort = false; // 排序完成后重置标记
            }
            stackSize--; // 减少堆栈大小
        }
    });

    return operations; // 返回总排序操作次数
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

标签:head,java,队列,双端,remove,js,命令,add,排序
From: https://blog.csdn.net/CodeClimb/article/details/144531773

相关文章

  • 【华为OD-E卷-取出尽量少的球 100分(python、java、c++、js、c)】
    【华为OD-E卷-取出尽量少的球200分(python、java、c++、js、c)】题目某部门开展FamilyDay开放日活动,其中有个从桶里取球的游戏,游戏规则如下:有N个容量一样的小桶等距排开,且每个小桶都默认装了数量不等的小球,每个小桶装的小球数量记录在数组bucketBallNums中,游戏开......
  • 【开源免费】基于SpringBoot+Vue.JS学生评奖评优管理系统(JAVA毕业设计)
    本文项目编号T096,文末自助获取源码\color{red}{T096,文末自助获取源码}......
  • 【开源免费】基于SpringBoot+Vue.JS植物健康系统(JAVA毕业设计)
    本文项目编号T095,文末自助获取源码\color{red}{T095,文末自助获取源码}......
  • RTSP播放器EasyPlayer.js遇到Android播放器修复播放画面卡在第一帧问题
    在数字化时代,流媒体技术已经成为信息传播和娱乐消费的重要方式。随着互联网技术的飞速发展和移动设备的普及,流媒体服务正在重塑我们的生活和工作方式。从视频点播、在线直播到音乐流媒体,流媒体技术的广泛应用不仅改变了内容的分发和消费模式,也为内容创作者和消费者提供了前所未有......
  • JSP
    1.JSPJSP全称JavaServerPage,基于Java语言,是一种动态网页技术。JSP使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。JSP本质是简化版的Servlet,JSP在编译后就变成了Servlet。JVM只能识别Java的类,是无法识别JSP代码的。所以WEB服务器会将JSP编译成JVM能识别......
  • JDK-8中的JAVA_OPTS通常用于传递给JVM的启动参数
    在JDK8中,JAVA_OPTS通常用于传递给JVM的启动参数。以下是一些常见的JAVA_OPTS项及其说明:内存管理-Xms:设置Java堆的初始大小,例如-Xms512m。-Xmx:设置Java堆的最大大小,例如-Xmx1024m。-Xmn:设置年轻代的大小。-XX:PermSize=size:设置永久代的初始大小(在JDK8中被Metaspace取代......
  • 老榕树的Java专题:XA的二阶提交
    XA(二阶提交)执行原理准备阶段(PreparePhase)事务协调者(TransactionCoordinator,TC)向所有参与事务的资源管理器(ResourceManager,RM)发送准备请求。例如,在一个包含数据库A和数据库B的分布式事务中,TC会分别向管理数据库A和数据库B的RM发送准备消息。RM接收到准备请求......
  • 老榕树的Java专题:知识分享(持续更新)
    1、线程的创建:        callable方式://创建一个类publicclassThreadTest{ //这里只是用于测试,正常开发中很少有这样的main执行的publicstaticmain(Stringargs[]){  //创建callable类Callable<String>call=newMyCallable();......
  • Java程序员面试前怎么准备才能从容应对当下的面试?
    现在互联网大环境不好,互联网公司纷纷裁员并缩减HC,更多程序员去竞争更少的就业岗位,整的IT行业越来越卷。身为Java程序员的我们就更不用说了,上班8小时需要做好本职工作,下班后还要不断提升技能、技术栈,才能从容应对现在互联网公司的面试!但事实是:很多Java程序员,对自身是没有一个清......
  • Java程序员如何获取高并发经验?
    现在好点的互联网公司招聘基本都要求有高并发经验,但没有高并发的经验的人感觉只有在好点的互联网才获得高并发经验,这难道不是死循环?没有高并发经验的人如何才能获取高并发方面的经验呢?如何获取高并发经验?其实并不是去了大公司就能获得高并发的经验,高并发只是一个结果,并不是过......