我所想到的:
对于任意的k,不能有A[k] * 2 = A[i] + A[j],就说明对于任意的k、所有的i<k,j>k,不能有A[k]-A[i]=A[j]-A[k]成立
discussion里面看到的一个想法:
采用分治的思想,但不是分为[0,N/2]和[N/2+1,N],而是分成奇数和偶数
由一个已知的beautiful array来构造另一个beautiful,可以通过
推论1.已知array每一项加上同一个数得到的array仍是beautiful的;
推论2.已知array每一项乘以同一个数得到的array仍是beautiful的。
所以 根据推论1:如果res是bea,那么res中的每一个元素i×2-1之后得到的array1也是bea;如果res是bea,那么res中的每一个元素i×2之后得到的array2也是bea。
再根据推论2:如果array1和array2都是bea,那么array+array2也是bea。
根据以上的结论,初始构造res={1}重复上述两个步骤直到新array的size=N就可以得到新的beautiful array
class Solution {
public int[] beautifulArray(int N) {
ArrayList<Integer> res = new ArrayList<>();
res.add(1);
while( res.size() < N ){
ArrayList<Integer> tmp = new ArrayList<>();
for( int i : res )
if( i * 2 - 1 <= N )
tmp.add(i * 2 - 1);
for( int i : res )
if( i * 2 <= N )
tmp.add(i * 2);
res = tmp;
}
return res.stream().mapToInt(i->i).toArray();
}
}
但是速度好像不快==
看了另一个想法:
class Solution {
public int[] beautifulArray(int n) {
int[] ans = new int[n];
solve(0, n - 1, 1, 1, ans);
return ans;
}
void solve(int left, int right, int a, int s, int[] nums) {
if(left > right)
return;
if(left == right) {
nums[left] = a;
return;
}
int mid = (left + right) / 2;
solve(left, mid, a, s * 2, nums);
solve(mid + 1, right, a + s, s * 2, nums);
}
}
solve(left, mid, a, s * 2, nums);
solve(mid + 1, right, a + s, s * 2, nums);
恩。。。整体想法没看懂,但是我列举了一下每次递归的参数变化发现:
(a,s+2)中a的值是1,5,3,7...
(a+s,s*2) 中a+s的值是2,6,4,8...
而且还有语句nums[left] = a;我想应该也是按照奇偶分的吧。。。