leetcode——932.漂亮数组/

漂亮数组:

对于某些固定的 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

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

时间: 2024-09-30 13:26:24

leetcode——932.漂亮数组/的相关文章

Leetcode:Subsets 求数组的所有子集

Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [

LeetCode:删除排序数组中的重复项||【80】

LeetCode:删除排序数组中的重复项||[80] 题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 . 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums =

[Swift Weekly Contest 108]LeetCode932. 漂亮数组 | Beautiful Array

For some fixed N, an array A is beautiful if it is a permutation of the integers 1, 2, ..., N, such that: For every i < j, there is no k with i < k < j such that A[k] * 2 = A[i] + A[j]. Given N, return any beautiful array A.  (It is guaranteed th

漂亮数组 Beautiful Array

2019-04-06 16:09:56 问题描述: 问题求解: 本题还是挺有难度的,主要是要考虑好如何去进行构造. 首先考虑到2 * A[i] = A[j] + A[k],那么j,k就必须是同奇同偶,否则它们的和必为奇数,显然等式不成立. 那么如果我们将N的数组分成两个部分,一部分全奇数,一部分全偶数,并且这两个部分是Beautiful Array,那么将它们concat一下,得到的也是Beautiful Array. 那么如何得到这两个部分呢? 这就需要一些数学的证明了,很容易证明得到漂亮数组

漂亮数组解法

漂亮数组:给定一个长度为N的数组arr,该数组由1到N的整数来组成,且满足arr[k]*2不等于arr[i]+arr[j]  (i<k<j) 例如: 长度为4的数组:{2,1,4,3} 长度为8的数组:[1,5,3,7,2,6,4,8] 假设一个数组为漂亮数组,则该数组一定满足下列条件: (1)数组中的每一个数加上一个任意整数,依旧维持漂亮数组. 例如:将{2,1,4,3}全部加一 得到  {3,2,5,4}  依旧满足 (2)将数组中的每一个数都乘上一个非0整数,依旧满足 例如:将{2,1,

前端与算法 leetcode 189. 旋转数组

目录 # 前端与算法 leetcode 189. 旋转数组 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 189. 旋转数组 题目描述 189. 旋转数组 概要 把他当做一到简单的题来做,不要想太多了就好也可以不整那些花里胡哨的,直接旋转数组n次,我一开始也想到了这个办法,但是觉得太简单而且效率低下,想了很久也没想到合适的办法 提示 使用额外的数组 解析 用一个额外的数组将每个元素放到对应的位置就好 下标为i的位置对应(i+k)%数组长度 ,然后把新的数组拷贝(深拷贝)到原

关于leetcode中对数组O(1)空间消耗操作的几道题

其实这几道题在leetcode中都是比较容易的,但是如果刚开始不理解题意的话可能就会进入陷阱. 整数数组中的几个操作如下面所示,无非是怎样进行数组元素的的交换. Remove Element Given an array and a value, remove all instances of that value in place and return the new length. The order of elements can be changed. It doesn't matter

leetcode之有序数组的平方

题目描述: 给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序. 示例 1: 输入:[-4,-1,0,3,10] 输出:[0,1,9,16,100] 示例 2: 输入:[-7,-3,2,3,11] 输出:[4,9,9,49,121] 解题:非递减顺序排序的整数数组,如果存在负数,即是说元素平方后,原序列的整体大小情况是:大--小--大,这时候我们采用头尾指针的方式:头部第一个元素与尾部最后一个元素相互比较,即可得出最大的元素,将这个元素存进辅助数组最大

LeetCode.1013-分割数组为三个和相同的部分

这是小川的第378次更新,第406篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第240题(顺位题号是1013).给定一个整数数组A,当且仅当我们可以将数组分成具有相等和的三个非空部分时才返回true. 形式上,我们可以对数组进行分区,如果我们能找到索引i + 1 <j使得 A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length-1]