优美的排列(力扣第667题)

667.优美的排列

给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件:

① 如果这个数组是 [a1, a2, a3, ... , an] ,那么数组 [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] 中应该有且仅有 k 个不同整数;.

② 如果存在多种答案,你只需实现并返回其中任意一种.

示例 1:

输入: n = 3, k = 1
输出: [1, 2, 3]
解释: [1, 2, 3] 包含 3 个范围在 1-3 的不同整数, 并且 [1, 1] 中有且仅有 1 个不同整数 : 1

示例 2:

输入: n = 3, k = 2
输出: [1, 3, 2]
解释: [1, 3, 2] 包含 3 个范围在 1-3 的不同整数, 并且 [2, 1] 中有且仅有 2 个不同整数: 1 和 2

分析:

​ 可以采用连续翻转的方法,比如n=5,即[1,2,3,4,5],

k = 1 1,2,3,4,5
k = 2 1,5,4,3,2
k = 3 1,5,2,3,4
k = 4 1,5,2,4,3

​ 用k=1时的数组作为连续数组,根据k的值决定固定不参与翻转的数为前k-1个,然后剩余的直接进行逆序翻转。

public int[] constructArray(int n, int k) {

    int[] res = new int[n];

    for (int i = 0; i < res.length; i++) {
        res[i] = i+1;
    }

    for (int i = 2; i <= k; i++) {
        swapArray(res,i);
    }

    return res;
}

private void swapArray(int[] array,int k){

    int temp;
    int left = k-1;
    int right = array.length - 1;

    while (left < right){

        temp = array[left];
        array[left] = array[right];
        array[right] = temp;
        left++;
        right--;
    }
}

​ 解法二:还有一种解法参考了cyc2018大神的,就是根据给定的k,让前k+1个元素构建出k个不同的差值,具体的构建方法就是首先定义一个差值变量,初始值为k,从数组第二个元素出发开始遍历,在奇数位置上是,赋值为当前元素的前一个元素值加上这个差值,偶数位置上则是当前元素的前一个位置元素值减去这个差值。每访问一个元素,差值变量减去1,直到前k+1个元素构建完成,然后剩余的元素则是从第k+2个元素出发,直接赋值给这些元素正常的顺序值,也就是索引值加1。

    public int[] constructArray(int n, int k) {

    int[] ret = new int[n];
    ret[0] = 1;
    for (int i = 1, interval = k; i <= k; i++, interval--) {
        ret[i] = i % 2 == 1 ? ret[i - 1] + interval : ret[i - 1] - interval;
    }
    for (int i = k + 1; i < n; i++) {
        ret[i] = i + 1;
    }
    return ret;
    }
posted @ 2020-12-02 15:44  有心有梦  阅读(131)  评论(0编辑  收藏  举报