497.队列 题解及思路
497.队列
问题描述
题目描述如下: 给定一个长度为 ( n ) 的序列 ( ),你可以选择删去其中最多 () 个数,得到一个新序列 ( ) (( )),新序列保留原来的相对顺序。你的目标是删除某些数,使得新序列的第 ( ) 个数 ( )。现在需要求出最少删除多少个数才能得到这样的序列,如果无法得到,输出 ()。
示例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
解释: 无法令,返回-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的值和flag与n的差值来判断是否有满足b数组的元素
flag,初始值设为 0,循环中判断flag+1是否等于,等于则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
}