932. Beautiful Array

我所想到的:

对于任意的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;我想应该也是按照奇偶分的吧。。。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值