我愿称之为丑陋数组好吧
时隔数日,重做了一遍,在一开始想思路的时候,想得有点久,其实两句话概括。
// 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(odd))