leetcode 2366. 配列をソートするための最小置換数 (配列ソートの最小置換数)

ここに画像の説明を挿入します

配列 nums の要素 nums[i] は、a+b = nums[i] の場合、任意の 2 つの数値 a、b に置き換えることができます。配列 nums を昇順に変更するために必要な置換の数 (等しい場合もあります
)配列。

アイデア:

ソートされた配列は、右側の要素を境界として、左側の要素 <= 右の要素になります。
したがって、配列は右から左に走査され、右端の要素を処理する必要はありません。

分割するときは、均等に分割するのが最善です。たとえば、10 を 5 と 5 に分割し、11 を 5 と 6 に分割するのが最適です。これにより、左にトラバースするときに、右側の要素が同じ大きさになるようにすることができます
。可能な限り分割の頻度を減らします。
たとえば、[5,10,8] の場合、10 を 5 と 5 に分割して [5,5,5,8] を得るのが最適です。その後、分割する必要があるのは 1 回だけです。10 を 2 と 8 に分割した
場合, [5,2, 8,8] が得られ、左端の要素 5 が 2 回分割されます。

分割された最小の数値 (左端の数値) は、次の要素の右側の境界です。

右境界の数値が正しい場合、分割数は cnt = (nums[i] - 1) / right となり、
最小の数値は nums[i] / (cnt + 1) となり、この数値に右を更新します。 。

nums[i] 自体が <=right の場合は、直接 right を nums[i] に更新し、次の反復に入ります。

値の範囲に注意し、結果にはlong型を使用してください。

    public long minimumReplacement(int[] nums) {
    
    
       int n = nums.length;
       int right = nums[n-1];
       long res = 0;

       for(int i = n-2; i >= 0; i--) {
    
    
           if(nums[i] > right) {
    
    
               int splitCnt = (nums[i] - 1) / right;
               right = nums[i] / (splitCnt + 1);
               res += splitCnt;
           } else {
    
    
               right = nums[i];
           }
       }
       return res;
    }

おすすめ

転載: blog.csdn.net/level_code/article/details/132846794