码迷,mamicode.com
首页 > 编程语言 > 详细

leetcode——932.漂亮数组/

时间:2019-10-07 13:29:16      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:三元   分治   返回   个数   n+1   elf   简单的   turn   https   

 

 

漂亮数组:

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

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

那么数组 A 是漂亮数组。

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

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

这个如何用分治算法呢?

分析

首先我们可以发现一个不错的性质,如果某个数组 是漂亮的,那么对这个数组进行仿射变换,得到的新数组 也是漂亮的。那么我们就有了一个想法:将数组分成两部分 left 和 right,分别求出一个漂亮的数组,然后将它们进行仿射变换,使得不存在满足下面条件的三元组:

A[k] * 2 = A[i] + A[j], i < k < j;
A[i] 来自 left 部分,A[j] 来自 right 部分。
可以发现,等式 A[k] * 2 = A[i] + A[j] 的左侧是一个偶数,右侧的两个元素分别来自两个部分。要想等式恒不成立,一个简单的办法就是让 left 部分的数都是奇数,right 部分的数都是偶数。

因此我们将所有的奇数放在 left 部分,所有的偶数放在 right 部分,这样可以保证等式恒不成立。对于 [1..N] 的排列,left 部分包括 (N + 1) / 2 个奇数,right 部分包括 N / 2 个偶数。对于 left 部分,我们进行 k = 1/2, b = 1/2 的仿射变换,把这些奇数一一映射到不超过 (N + 1) / 2 的整数。对于 right 部分,我们进行 k = 1/2, b = 0 的仿射变换,把这些偶数一一映射到不超过 N / 2 的整数。经过映射,left 和 right 部分变成了和原问题一样,但规模减少一半的子问题,这样就可以使用分治算法解决了。

算法

在 [1..N] 中有 (N + 1) / 2 个奇数和 N / 2 个偶数。我们将其分治成两个子问题,其中一个为不超过 (N + 1) / 2 的整数,并映射到所有的奇数;另一个为不超过 N / 2 的整数,并映射到所有的偶数。

作者:LeetCode
链接:https://leetcode-cn.com/problems/beautiful-array/solution/piao-liang-shu-zu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution:
    def beautifulArray(self, N):
        memo={1:[1]}#边界条件
        def f(N):#装饰器
            if N not in memo:
                odds=f((N+1)//2)
                evens=f(N//2)
                memo[N]=[2*x-1 for x in odds]+[2*x for x in evens]
            return memo[N]
        return f(N)

                                    ——2019.10.7

 

leetcode——932.漂亮数组/

标签:三元   分治   返回   个数   n+1   elf   简单的   turn   https   

原文地址:https://www.cnblogs.com/taoyuxin/p/11629834.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!