算法题 漂亮数组

LeetCode 932

对于某些固定的 N,如果数组 A 是整数 1, 2, ..., N 组成的排列,使得:

对于每个 i < j,都不存在 k 满足 i < k < j 使得 A[k] * 2 = A[i] + A[j]

那么数组 A 是漂亮数组。

 

给定 N,返回任意漂亮数组 A(保证存在一个)。

 

示例 1:

输入:4
输出:[2,1,4,3]

示例 2:

输入:5
输出:[3,1,2,5,4]

 

提示:

  • 1 <= N <= 1000

解法: https://www.acwing.com/solution/leetcode/content/588/

算法
(分治) Θ(nlogn)Θ(nlog⁡n)
对于一个连续的数列 1,2,3,…,n1,2,3,…,n,如果按照奇偶分成两部分,1,3,5,…1,3,5,… 放到左边,2,4,6,8,…2,4,6,8,… 放到右边。这样重新安排后,如果 ii 属于左边,jj 属于右边,A[i]+A[j]A[i]+A[j] 就必定是奇数,因而不存在 A[k]A[k],满足 A[k]∗2=A[i]+A[j]A[k]∗2=A[i]+A[j]。
接下来再看每一部分的内部,由于 1,3,5,…1,3,5,… 也是等差数列,所以可以经过变换再次变成 1,2,3,…1,2,3,…,且变换后的数列如果满足题目的性质,则原数列同样满足。如果我们仍然按照 1 中的策略进行奇偶分离,则可以继续分为两部分递归处理。同理 2,4,6,…2,4,6,… 也可以进行变换然后递归。
最后递归的出口是仅有一个数字时,直接返回。
实际上,不需要显式的进行变换,只需要在每一次递归时,将当前数组中,位于奇数位置的数字按原顺序放到前边,之后放置位于偶数位置的数字按原顺序,然后递归即可。


时间复杂度
每一层的时间复杂度为 Θ(n)Θ(n),一共有 lognlog⁡n 层,故总时间复杂度为 Θ(nlogn)Θ(nlog⁡n)。

代码:

    public int[] beautifulArray(int N) {   
        int[] ans = new int[N];
        for (int i = 0; i < N; i++)
            ans[i] = i + 1;
        solve(0, N - 1, ans);
        return ans;
    }
	
	public void solve(int l, int r, int[] ans){
		if(l == r)
			return;
		int[] tmp = new int[r-l+1];
		int cnt = 0;
		for (int i = l; i <= r; i += 2)
            tmp[cnt++] = ans[i];
        for (int i = l + 1; i <= r; i += 2)
            tmp[cnt++] = ans[i];

        for (int i = l; i <= r; i++)
            ans[i] = tmp[i - l];
        int mid = (l + r) / 2;
        solve(l, mid, ans);
        solve(mid + 1, r, ans);
	}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值