497.队列 题解及思路 | 豆包MarsCode AI刷题

51 阅读2分钟

497.队列 题解及思路

497.队列

问题描述

题目描述如下: 给定一个长度为 ( n ) 的序列 ( a1,a2,,ana_1, a_2, \dots, a_n ),你可以选择删去其中最多 (n1 n-1) 个数,得到一个新序列 ( b1,b2,,bmb_1, b_2, \dots, b_m ) (( 1mn1 \le m \le n )),新序列保留原来的相对顺序。你的目标是删除某些数,使得新序列的第 ( ii ) 个数 ( bi=ib_i = i )。现在需要求出最少删除多少个数才能得到这样的序列,如果无法得到,输出 (1-1)。

示例1:

输入:n = 5 ,a = [1, 4, 2, 3, 5]
输出:2

解释: 删除a[1]a[4],b = [1, 2, 3]

示例2:

输入:n = 3 ,a = [3, 3, 2]
输出:-1

解释: 无法令bi=ib_i = i,返回-1

示例3:

输入:n = 5 ,a = [1, 2, 3, 4, 5]
输出:0

解释: 不需要删除,返回0

解题思路

思路1

初始化一个计数器变量 count,统计删除的元素个数

定义一个标记变量 flag,初始值设为 1,通过判断当前元素是否与flag对应,对应则表示为需要添加到数组中的元素,反之则为需要删除的元素

创建一个 ArrayList 类型的列表 temp,存储符合连续递增要求的数组元素,即我们的b数组

使用 if (a[i]!= flag) 判断当前数组元素 a[i] 是否等于当前期望的值 flag(也就是是否符合连续递增的顺序要求),如果不相等,说明这个元素是我们需要删除的元素,就将计数器 count 的值加 1,然后使用 continue 语句跳过本次循环后面的代码,直接进入下一次循环,继续检查下一个数组元素。如果相等,则将我们的flag添加到temp中,并将flag+1。

判断temp的长度是否为0,说明没有符合题目要求的b数组则返回-1

java代码
public static int solution(int n, int[] a) {
    // write code here
    int count = 0;
    int flag = 1;
    List<Integer> temp = new ArrayList<>();
    for (int i = 0; i < a.length; i++) {
        if (a[i] != flag){
            count++;
            continue;
        }
        temp.add(flag);
        flag++;
    }
    int size = temp.size();
    if (size == 0){
        return -1;
    }
    return count; // placeholder return
}

思路2

在思路1的基础上进行空间优化,不使用temp来存放元素,依靠flag的值和flagn的差值来判断是否有满足b数组的元素

flag,初始值设为 0,循环中判断flag+1是否等于aia_i,等于则flag++

循环结束后判断n-flag == n,相等则说明a中没有符合b数组的元素,返回-1 否则返回n-flag

public static int solution(int n, int[] a) {
    // write code here
    int flag = 0;
    for (int i = 0; i < a.length; i++) {
        if (a[i] == flag +1){
            flag++;
        }
    }
    if (n-flag == n){
        return -1;
    }
    return n-flag; // placeholder return
}