932. 漂亮数组
-
分治的思想,怎么解决?
-
首先一个数组a[]是漂亮数组,代表n个元素1,2,…,n的排列满足
任意的i,j,k,i<k<j, 都不存在 2 ∗ a [ k ] = a [ i ] + a [ j ] 2*a[k]=a[i]+a[j] 2∗a[k]=a[i]+a[j]
-
首先我们注意到,上面式子的左边必定是偶数,那么如果右边必定是奇数,满足条件。
-
怎么满足左边必定是偶数,右边必定是奇数,将1,2,3,…,n这n个数字分成两个部分,左边全放奇数,右边全放偶数,这样就可以,这样的话如果i在左边,j在右边,那么对于这样的k,我们的构造必定满足条件。
1,2,3,…,n这么多的数字中有(n+1)/2个奇数,有n/2个偶数,那么左边 放(n+1)/2个奇数,右边放n/2个偶数。
现在还有一种情况可能不满足条件,那就是i,j指示的三个数字在一边,都在左边或者都在右边,都在右边的话可能会出现问题。
如何解决这两种情况?
如果左右两边也递归的满足这种性质?是不是就可以解决?
-
如果 a [ i ] + a [ j ] = 2 ∗ a [ k ] a[i]+a[j]=2*a[k] a[i]+a[j]=2∗a[k],那么 k 1 ∗ a [ i ] + b + k 1 ∗ a [ j ] + b = 2 ∗ ( k 1 ∗ a [ k ] + b ) k1*a[i]+b+k1*a[j]+b=2*(k1*a[k]+b) k1∗a[i]+b+k1∗a[j]+b=2∗(k1∗a[k]+b), 这是一个线性关系。
-
那么我们最优两边的奇数和偶数分别映射到1,2,…,(n+1)/2和1,2,…,(n)/2这两个数上面去。
也就是左边的奇数映射到—(左边的奇数+1)/2上面去,右边的偶数映射到—(右边的偶数)/2上面去,这样的话就递归的变成了上面的问题。
class Solution { public: // 1. 判断排列 // 2. map<int,vector<int>>mp; vector<int> solve(int n){ if(!mp.count(n)){ vector<int>left=solve((n+1)/2); vector<int>right=solve(n/2); for(auto&val:left){ val=2*val-1; } for(auto&val:right){ val=2*val; } mp[n].insert(mp[n].end(),left.begin(),left.end()); mp[n].insert(mp[n].end(),right.begin(),right.end()); } return mp[n]; } vector<int> beautifulArray(int N) { mp[1]=vector<int>({1}); solve(N); return mp[N]; } };