【备战秋招】每日一题: 2022.9.17-美团机试-栈の合并

为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1013

题目内容

塔子哥刚学完栈这个数据结构,觉得非常的神奇。现在作为acm的预选队员之一,他被学长的一个问题给问趴下了。三天没有任何进展,你能帮帮他吗?

“栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。

塔子哥拿到了两个栈,现在需要将两个栈里面的元素合并为一个n排列。(也就是1~n各出现一次)

现在塔子哥允许有两个操作:

1.选择其中一个栈并弹出栈顶。但是被弹出的元素必须要是两个栈之间的最小值

2.将其中一个栈的栈顶元素弹出,之后放入另外一个栈的栈顶。

求能够完成任务最小操作次数

输入描述

第一行为 n n n s z 1 sz_1 sz1, s z 2 sz_2 sz2 n n n即为要组成的 n n n排列大小, s z 1 sz_1 sz1, s z 2 sz_2 sz2为两个栈的大小,其中 0 < n < 1000 0<n<1000 0<n<1000, s z 1 + s z 2 = n sz_1+sz_2=n sz1+sz2=n

第二行 s z 1 sz_1 sz1个整数 d ( 0 < d < = n ) d(0<d<=n) d(0<d<=n),表示第一个栈从栈底到栈顶的 s z 1 sz_1 sz1个元素

第三行 s z 2 sz_2 sz2个整数 d ( 0 < d < = n ) d(0<d<=n) d(0<d<=n),表示第二个栈从栈底到栈顶的 s z 2 sz_2 sz2个元素

样例

输入

4 2 2
1 3
4 2

输出

6

题目思路

核心:让最小值暴露在栈顶然后弹出去。

思路:

1.求两个栈的最小值并确定该最小值所在的栈

2.通过操作1让最小值暴露在栈顶

3.执行操作2

上述三步反复进行n步即可

代码

Java代码

import java.util.*;

public class Main {
    // 获取最小值
    public static int getMin (Stack<Integer> a){
        Stack<Integer> c = new Stack<>();
        int mxa = 10000000;
        // 将栈导出到临时栈c中,同时取最小值
        while (a.empty() == false){
            mxa = Math.min(mxa , (Integer)a.peek());
            c.push(a.peek());
            a.pop();
        }
        // c -> a
        while (c.empty() == false){
            a.push(c.peek());
            c.pop();
        }
        return mxa;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int x = in.nextInt();
        int y = in.nextInt();
        // 开两个栈模拟该过程
        Stack<Integer> a = new Stack<>();
        Stack<Integer> b = new Stack<>();
        for (int i = 1 ; i <= x ; i++){
            int s = in.nextInt();
            a.push(s);
        }
        for (int i = 1 ; i <= y ; i++){
            int s = in.nextInt();
            b.push(s);
        }
        int ans = 0;
        // 总共会有n轮
        // 每一轮先1.找出栈中的最小值以及其所在的栈 2.将最小值上面的所有数pop到另外一个栈中去
        for (int i = 1 ; i <= n ; i++){
            //选择栈的最小值
            int mxa = getMin(a);
            int mxb = getMin(b);
            // 判断在哪个栈
            if (mxa == Math.min(mxa , mxb)){
                // 将最小值上面的所有数pop到另外一个栈中去
                while ((Integer)a.peek() != mxa){
                    b.push(a.peek());
                    a.pop();
                    ans++;
                }
                a.pop();
                ans++;
            }else {
                // 将最小值上面的所有数pop到另外一个栈中去
                while ((Integer)b.peek() != mxb){
                    a.push(b.peek());
                    b.pop();
                    ans++;
                }
                b.pop();
                ans++; 
            }
        }
        System.out.println(ans);
    }
}

C++代码

#include <bits/stdc++.h>
using namespace std;

// 获取最小值
int getMin (stack<int> a) {
    stack<int> c ;
    int mxa = 10000000;
    // 将栈导出到临时栈c中,同时取最小值
    while (a.empty() == false) {
        mxa = min(mxa , a.top());
        c.push(a.top());
        a.pop();
    }
    // c -> a
    while (c.empty() == false) {
        a.push(c.top());
        c.pop();
    }
    return mxa;
}
int main()
{
    int n, x, y;
    cin >> n >> x >> y;
    stack<int> a;
    stack<int> b;
    for (int i = 1 ; i <= x ; i++) {
        int s ;
        cin >> s;
        a.push(s);
    }
    for (int i = 1 ; i <= y ; i++) {
        int s ;
        cin >> s;
        b.push(s);
    }
    int ans = 0;
    // 总共会有n轮
    // 每一轮先1.找出栈中的最小值以及其所在的栈 2.将最小值上面的所有数pop到另外一个栈中去
    for (int i = 1 ; i <= n ; i++) {
        //选择栈的最小值
        int mxa = getMin(a);
        int mxb = getMin(b);
        // 判断在哪个栈
        if (mxa == min(mxa , mxb)) {
            // 将最小值上面的所有数pop到另外一个栈中去
            while ((int)a.top() != mxa) {
                b.push(a.top());
                a.pop();
                ans++;
            }
            a.pop();
            ans++;
        } else {
            // 将最小值上面的所有数pop到另外一个栈中去
            while ((int)b.top() != mxb) {
                a.push(b.top());
                b.pop();
                ans++;
            }
            b.pop();
            ans++;
        }
    }
    cout<<ans<<endl;
}

Python代码

def getMin(a):
    c = []
    mxa = 1000000000
    while len(a) > 0:
        mxa = min(mxa, a[len(a)-1])
        c.append(a[len(a)-1])
        a.pop()
    while len(c) > 0:
        a.append(c[len(c)-1])
        c.pop()
    return mxa


n, x, y = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
ans = 0
for i in range(n):
    mxa = getMin(a)
    mxb = getMin(b)
    if (mxa == min(mxa, mxb)):
        while a[len(a)-1] != mxa:
            b.append(a[len(a)-1])
            a.pop()
            ans += 1
        a.pop()
        ans += 1
    else:
        while b[len(b)-1] != mxb:
            a.append(b[len(b)-1])
            b.pop()
            ans += 1
        b.pop()
        ans += 1
print(ans)

Js代码

process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';

process.stdin.on('data', (data) => {
	input += data;
	return;
});
process.stdin.on('end', () => {
    function getMin(a) {
    let c=new Array();
    let mxa = 10000000;
    // 将栈导出到临时栈c中,同时取最小值
    while (a.length>0) {
        mxa = Math.min(mxa , a[a.length-1]);
        c.push(a[a.length-1]);
        a.pop();
    }
    // c -> a
    while (c.length>0) {
        a.push(c[c.length-1]);
        c.pop();
    }
    return mxa;
}
    let n, x, y;
    input=input.split('\n');
    n=Number(input[0].split(' ')[0]);
    x=Number(input[0].split(' ')[1]);
    y=Number(input[0].split(' ')[2]);
    let a=new Array();
    let b=new Array();
    for (let i = 1 ; i <= x ; i++) {
        let s=Number(input[1].split(' ')[i-1]);
        a.push(s);
    }
    for (let i = 1 ; i <= y ; i++) {
        let s =Number(input[2].split(' ')[i-1]);
        b.push(s);
    }
    let ans = 0;
    // 总共会有n轮
    // 每一轮先1.找出栈中的最小值以及其所在的栈 2.将最小值上面的所有数pop到另外一个栈中去
    for (let i = 1 ; i <= n ; i++) {
        //选择栈的最小值
        let mxa = getMin(a);
        let mxb = getMin(b);
        // 判断在哪个栈
        if (mxa == Math.min(mxa , mxb)) {
            // 将最小值上面的所有数pop到另外一个栈中去
            while (a[a.length-1] != mxa) {
                b.push(a[a.length-1]);
                a.pop();
                ans++;
            }
            a.pop();
            ans++;
        } else {
            // 将最小值上面的所有数pop到另外一个栈中去
            while (b[b.length-1] != mxb) {
                a.push(b[b.length-1]);
                b.pop();
                ans++;
            }
            b.pop();
            ans++;
        }
    }
    console.log(ans);
})

题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值