漂亮数组算法

我愿称之为丑陋数组好吧


时隔数日,重做了一遍,在一开始想思路的时候,想得有点久,其实两句话概括。

// 1
// 1 2
// 1 3 2
// 1 3 2 4

要求两个数的漂亮数组,要从一个数的出发,将一个数乘2-1变为奇数放在左边,乘2变为偶数放在右边,就得到两个数的漂亮数组了。

要求三个数的漂亮数组,首先得到它的奇数有两个,偶数有一个。

那么这两个奇数,就右两个数的漂亮数组转换而来。将两个数的漂亮数组,也就是1,2均乘2-1,得到奇数1 3放在左边

偶数部分 只有1个,则将一个的漂亮数组1*2 放在右边。拼接即成。

就好像六个数的漂亮数组,就将三个数的漂亮数组乘2-1放在左边,乘2放在右边,就得到六个数的漂亮数组。

原理看下面。

主要讲代码,还是在那个如何将前一个数组乘两倍放到新数组来 这里想了很久。

后面看了答案才醍醐灌顶,加强for循环将其每个输出阿,但是最主要,最精髓的还是那个t++吧;

每次递归都创建一个新的数组,然后因为要从下一个递归返回的数组取出来,那就用一个加强for循环将上个数组依次输出,然后该数组用t++向前移动,妙阿实在是妙阿。


确实,是一道非常无语的题目,感觉性质确实不好想,但是为了体现分治的想法,倒也还是不错滴。

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

确实是想不出来,只能看答案的思路,主要是答案的思路也解析得很傻逼,就是完全不想让别人看懂的程度(也或许是我太菜了)

而且有时候,真的是,看答案的文字解析百次还不如自己画出来推一变一次,就很清晰了。

答案的思路就是 将一个数组分为左右两部分,左部分全部都是奇数,右部分全部都是偶数。

然后只要奇数部分是漂亮数组,偶数部分也是漂亮数组,那么合起来也就是漂亮数组。

举个小栗子(答案就是不爱举例子,所以看得云里雾里)

在这里插入图片描述
所以其实算法思路是很容易想明白的,就是 要找N=4还是N=5,无论N=什么,首先要看N有多少个偶数和奇数,比如说5 就有 2个偶数,3个奇数。

那么奇数部分 就应该 1 3 2 (最小的3个漂亮数组去投射) 投射成 (*2 -1) 1 5 3
然后偶数部分 1 2 (最小的两个漂亮数组去投射)投射成(*2) 2 4
然后合起来 就得到 1 5 3 2 4

当然,你会发现 1 3 2 也是通过同样的方法找到的 3个数的漂亮数组,两个奇数投射 1 3
一个偶数 2 合并成 1 3 2
所以就是一个递归法分治的过程

 int []dfs(int k){
   
        if(k==1)
        {
   
            return new int[]{
   1};
        }
        int even=k/2;
        int odd=k-k/2;
        int[]leftnum=doubleodd(dfs
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值