667. Beautiful Arrangement II。

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 and k are in the range 1 <= k < n <= 104.


给了n和k,让我们构造一个数组,数组需要满足如下内容:数组中共有n个元素,并且n个元素为[1,n],而且需要满足数组中前一个数减去后一个数([a(n-1) - a(n)])得到的数字有k种。

数组很好构建,主要是如何满足k种结果。

可以得知,如果是n个数字的话,那么k最大的值为:n-1,此时的排列方式为:[1,n,2,n-1…];
k的最小值为:1,此时的排列方式为:[1,2,3,4…n]

所以可以将数组分为两部分,从n-k处分开:[1,2,n-k-1] 和 [n-k,…n]。如果我们让后半部分的排列方式与[1,n,2,n-1,…]的方式一致的话,后半部分就能够得到n-(n-k)=k种方式。前半部分之后得到一种结果:-1,而且后半部分的k中一定包括-1。这样前后部分再次组合起来就是k种结果。

例如:n=6,k=3

第一部分:[1,2],共有一种结果:-1。
第二部分:[3,6,4,5],共有三种结果,并且其中包括-1。

组合起来:[1,2,3,6,4,5],就是有三种,满足了k。

class Solution {
public:
    vector<int> constructArray(int n, int k) {
        vector<int> result(n);//构造一个n个元素的数组
        int num=0;//数组的下标

        //构造前半部分,只会产生1种结果
        for(int i=1; i < n-k; i++) {
            result[num++] = i;
        }

        //构造后半部分,能够产生k种结果
        for(int i=0; i <= k; i++) {
            //如果是下标为偶数就取第一个数,奇数取最后一个数
            result[num++] = (i%2 == 0) ? (n-k + i/2) : (n - i/2);
        }

        return result;

    }
};

上述的思路就是将数组分为两组,这种思想的另外一种代码:

class Solution{
public:
    vector<int> constructArray(int n, int k) {
        vector<int> res;
        int i = 1, j = n;
        while (i <= j) {
            if (k > 1) res.push_back(k-- % 2 ? i++ : j--);
            else res.push_back(i++);
        }
        return res;
    }
};

例如:
n=6,k=2:[6,1,2,3,4,5],分为两部分:[6]和[1,2,3,4,5]。
n=6,k=3:[1,6,2,3,4,5],分为两部分:[1,6]和[2,3,4,5]。
n=6,k=4:[6,1,5,2,3,4],分为两部分:[6,1,5]和[2,3,4]。
n=6,k=5:[1,6,2,5,3,4],分为两部分:[1,6,2,5]和[3,4]。

上述代码的思想就是:前半部分构造出k-2种结果,然后后半部分构造出1种结果,但是两部分组合起来的时候还会组合成一种,所以就是k种。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值