问题描述
给定一个长度为 的序列 ,你可以选择删去其中最多 个数,得到一个新序列 (),新序列保留原来的相对顺序。你的目标是删除某些数,使得新序列的第 个数 。现在需要求出最少删除多少个数才能得到这样的序列,如果无法得到,输出 。
例如,对于序列 [1, 4, 2, 3, 5],删除第 2 个和第 5 个元素后,可以得到序列 [1, 2, 3]。
样例
样例一:
输入:
n = 5 ,a = [1, 4, 2, 3, 5]
输出:2
样例二:
输入:
n = 3 ,a = [3, 3, 2]
输出:-1
样例三:
输入:
n = 5 ,a = [1, 2, 3, 4, 5]
输出:0
解题思路
-
理解问题:
- 我们需要找到一个子序列,使得这个子序列中的每个元素都等于其在子序列中的位置(从1开始)。
- 例如,对于序列
[1, 4, 2, 3, 5],删除第 2 个和第 5 个元素后,可以得到序列[1, 2, 3],这个序列满足条件。 - 通俗点说,这个序列就是要从1开始逐个递增。
-
数据结构选择:
- 由于我们需要保留元素的相对顺序,并且需要频繁地检查当前元素是否等于其期望的位置,使用数组或列表来存储序列是合适的。我们直接在原数组上统计即可。
-
算法步骤:
- 初始化一个变量
cur表示当前期望的元素值,初始值为1。 - 遍历原序列
a,对于每个元素a[i]:- 如果
a[i]等于cur,则说明当前元素是期望的元素,将cur增加1。 - 如果
a[i]不等于cur,则说明当前元素需要被删除,记录删除的次数。
- 如果
- 遍历结束后,如果
cur小于等于n,说明可以找到一个满足条件的子序列,返回删除的次数。 - 如果
cur大于n,说明无法找到满足条件的子序列,返回-1。
- 初始化一个变量
代码
public class Main {
public static int solution(int n, int[] a) {
int res = 0;
int cur = 1;
for (int i = 0; i < a.length; i++) {
if (a[i] != cur) {
res++;
} else {
cur++;
}
}
return res == a.length ? -1 : res; // placeholder return
}
public static void main(String[] args) {
System.out.println(solution(5, new int[]{1, 4, 2, 3, 5}) == 2);
System.out.println(solution(3, new int[]{3, 3, 2}) == -1);
System.out.println(solution(5, new int[]{1, 2, 3, 4, 5}) == 0);
}
}