Given two integers n
and k
, you need to construct a list which contains n
different positive integers ranging from 1
to n
and obeys the following requirement:
Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k
distinct integers.
If there are multiple answers, print any of them.
Example 1:
Input: n = 3, k = 1
Output: [1, 2, 3]
Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
Example 2:
Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
Note:
- The
n
andk
are in the range 1 <= k < n <= .
给出两个参数n和k,n代表数组的长度,并且数组中的元素为从1到n,k的计算遵循以下规则:
假设数组为[a1, a2, a3, ... , an],则计算数组 [|a1 - a2|, |a2 - a3|, ... , |an-1 - an|]中不同数字的个数即为k值。
暴力手段在这里我们就不提及了,就是逐个将[1, n]区间内的整数填充到数组中,计算是否满足条件,它的算法时间复杂度将达到O(N!),非常可怕。
我的解题思路和官方解法除法点不太一样,但是最后的处理却比较相似。
思路一(我的解法):
开始我在思考的时候也非常迷茫,因为任意指定的n和k,手动拼凑都要花费一些时间,但是随后我发现,k的最大值为n - 1,也就意味着当n = 6, k = 5时,差值序列就为[1, 2, 3, 4, 5],再进一步的说,差值为5的时候一定是1和6相邻,当只要差值和数组中的一个数字固定的时候,其他的结果就都计算出来了。假设6在最右侧,则对应的原数组就是[3, 4, 2, 5, 1, 6]。
当k为1的时候,差值序列为[1, 1, 1, 1, 5]可以么?答案是肯定的,对应的数组就是 [5, 4, 3, 2, 1, 6]。
那么对于任意的k,我们是不是可以假设差值序列除1外的部分为[n - k, n - k + 1, n - k + 2, ... , n - 1]。那么原数组中的最后一个值也就确定为n,然后根据这些条件求解原数组即可。
在代码实现的时候,我发现执行的代码是可以简化的,仔细观察[3, 4, 2, 5, 1, 6]这个n = 6, k = 5时的序列,其实就是倒序的按照 "two pointer"的方式用两个索引从区间两端交替的不断逼近中间得到的结果。如果k != n - 1,就需要在倒序到达n - k - 1处时,停止一个索引,用另一个索引不断向另一个索引的方向回填结果即可。
这个思路说起来有点抽象,建议配合下边的代码看哦~
我的解法:
class Solution {
public int[] constructArray(int n, int k) {
int[] result = new int[n];
int left = 1, right = n;
int i = n - 1;
boolean isRight = true;
while (left <= right) {
if (isRight) {
result[i--] = right--;
} else {
result[i--] = left++;
}
if (k > 1) {
isRight = !isRight;
--k;
}
}
return result;
}
}
如有错误,欢迎指摘。也欢迎通过左上角的“向TA提问”按钮问我问题,我将竭力解答你的疑惑。