校招算法笔面试 | 校招笔面试真题-序列操作

题目## 题目

题目链接

解题思路

  1. 题目要求对长度为 n n n 的序列进行 m m m 次操作,每次将选中的数字 k i k_i ki 移到序列最前面
  2. 关键点是要从后往前处理输入的操作序列,并用一个 visited 数组记录已经输出的数字
  3. 最后需要按顺序输出剩余未被访问过的数字
  4. 本质上是一个模拟题,需要注意处理顺序

代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<bool> visited(n + 1, false);
    vector<int> operations(m);
    
    // 读入操作序列
    for(int i = 0; i < m; i++) {
        cin >> operations[i];
    }
    
    // 从后向前处理操作
    for(int i = m - 1; i >= 0; i--) {
        if(!visited[operations[i]]) {
            cout << operations[i] << endl;
            visited[operations[i]] = true;
        }
    }
    
    // 输出剩余未访问的数字
    for(int i = 1; i <= n; i++) {
        if(!visited[i]) {
            cout << i << endl;
        }
    }
    
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        boolean[] visited = new boolean[n + 1];
        int[] operations = new int[m];
        
        // 读入操作序列
        for(int i = 0; i < m; i++) {
            operations[i] = sc.nextInt();
        }
        
        // 从后向前处理操作
        for(int i = m - 1; i >= 0; i--) {
            if(!visited[operations[i]]) {
                System.out.println(operations[i]);
                visited[operations[i]] = true;
            }
        }
        
        // 输出剩余未访问的数字
        for(int i = 1; i <= n; i++) {
            if(!visited[i]) {
                System.out.println(i);
            }
        }
    }
}
n, m = map(int, input().split())
visited = [False] * (n + 1)
operations = []

# 读入操作序列
for _ in range(m):
    operations.append(int(input()))

# 从后向前处理操作
for i in range(m-1, -1, -1):
    if not visited[operations[i]]:
        print(operations[i])
        visited[operations[i]] = True

# 输出剩余未访问的数字
for i in range(1, n + 1):
    if not visited[i]:
        print(i)

算法及复杂度

  • 算法:模拟 + 哈希表(visited数组)
  • 时间复杂度: O ( n + m ) \mathcal{O}(n + m) O(n+m) - 需要遍历一次操作序列和剩余数字
  • 空间复杂度: O ( n ) \mathcal{O}(n) O(n) - 需要一个visited数组记录访问状态

题目链接

解题思路

  1. 这是一个查找缺失数字的问题,可以使用求和的方法解决
  2. 解题步骤:
    • 计算从 0 0 0 n n n 的所有数字之和 s u m sum sum
    • 计算给定序列中所有数字之和 s u m 1 sum1 sum1
    • 两个和的差值就是缺失的数字
  3. 这种方法避免了排序,时间复杂度为 O ( n ) \mathcal{O}(n) O(n)

代码

#include <iostream>
using namespace std;

int main() {
    int n, sum = 0, sum1 = 0;
    cin >> n;
    
    // 计算0到n的和
    for(int i = 0; i <= n; i++) {
        sum += i;
    }
    
    // 计算给定序列的和
    for(int i = 0; i < n; i++) {
        int temp;
        cin >> temp;
        sum1 += temp;
    }
    
    // 输出差值
    cout << sum - sum1 << endl;
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int sum = 0, sum1 = 0;
        
        // 计算0到n的和
        for(int i = 0; i <= n; i++) {
            sum += i;
        }
        
        // 计算给定序列的和
        for(int i = 0; i < n; i++) {
            sum1 += sc.nextInt();
        }
        
        // 输出差值
        System.out.println(sum - sum1);
    }
}
nums = list(map(int, input().split()))
n = nums[0]
sum_total = sum(range(n + 1))
nums = nums[1:]
sum_given = sum(nums)

# 输出差值
print(sum_total - sum_given)

算法及复杂度

  • 算法:数学求和
  • 时间复杂度: O ( n ) \mathcal{O}(n) O(n) - 需要遍历一次序列
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要常数额外空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值