我有以下问题:如果每一个数字序列都单调递增(或简单地递增)
序列中的数字大于或等于其前面的数字。编写一个布尔函数increasing(int[] x, int length)
,如果给定数组包含给定长度的递增子序列,则返回true,否则返回false。准则:
?
increasing(int[] x, int length)
的签名我考虑过使用一个古老的问题,即增加最长的子序列,然后比较大小,如果给定的大小大于LIS,则它将返回false。但是,我的LIS代码似乎缺少跳过数字并重复数字的情况,例如9,7,5,4,7,1,-3,8
为3而不是true返回false,也为3,1,1,2
返回false。
public static boolean increasing(int[] x, int length) {
int i = 0;
int ans = longestIncreasing(x, length, i);
return (ans >= length);
}
private static int longestIncreasing(int[] arr, int n, int i) {
if (n == 0) {
return 1;
}
int m = 1, temp;
if (arr[i++] < arr[n--]) {
temp = 1 + longestIncreasing(arr, n, i);
if (temp > m) {
m = temp; // m = max(m, 1 + _lis(arr, i));
}
}
else {
longestIncreasing(arr, n--, i++);
}
return m;
}
答案 0 :(得分:2)
找到最长的递增序列似乎在这种情况下可能是更难解决的问题。查找一定长度的连续序列的问题仅需要在递归调用堆栈的每个级别的索引变量中添加一个,并将其与目标长度进行比较。因此,在简单的情况下,您的问题可以像这样解决:
public static boolean increasing(int[] x, int length) {
return increasing(x, length, 0);
}
private static boolean increasing(int[] x, int length, int depth) {
if (x.length < length) return false;
if (depth >= length) return true;
if (depth > 0 && x[depth - 1] > x[depth]) return false;
return increasing(x, length, depth + 1);
}
当您必须考虑非连续项目的序列时,它将变得更加复杂。在那种情况下,当遇到一个小于前一个元素的元素时,您无需在不增加深度的情况下向下移动调用堆栈,而是跟踪最后两个元素时要跳过多少个元素,而不是立即返回false
顺序条款。 (请注意,这需要额外检查以防止递归超出数组大小):
public static boolean increasing(int[] x, int length) {
return increasing(x, length, 0, 0);
}
private static boolean increasing(int[] x, int length, int depth, int skip) {
if (x.length < length) return false;
if (depth >= length) return true;
if (depth + skip >= x.length) return false;
if (depth > 0 && x[depth - 1] > x[depth + skip]) {
return increasing(x, length, depth, skip + 1);
}
return increasing(x, length, depth + 1, 0);
}
答案 1 :(得分:1)
NLS_LANG
演示:
public static boolean increasing(int[] x, int length) {
return increasing(x, length, x[0], 0, 0) >= length;
}
private static int increasing(int[] x, int length, int min, int i, int from) {
if (i >= x.length)
return 0;
int res = increasing(x, length, Math.max(min, x[i]), i + 1, from);
if (x[i] >= min)
res++;
if (i != from || res >= length || i + length > x.length)
return res;
return increasing(x, length, x[i + 1], i + 1, i + 1);
}