タイトルと分析
タイトル
非ゼロ要素の相対的な順序を維持しながらNUMS配列を指定し、すべての書き込み機能は、アレイ0の最後に移動しました。
例:
入力:[0,1,0,3,12]
出力:[1,3,12,0,0]
説明:
元の配列上で動作しなければならない、あなたは追加の配列をコピーすることはできません。
操作の数を最小限に抑えます。
分析
ローカル対象注:元の配列の操作は、スペースの制約に記載されている必要がありO(1)の複雑さを制限します。
より明確な意味題名:0は、配列の末尾に移動します。しかし、我々は、追加の配列を持つことができません。したがって、アレイ内の単一の運動は、交換使用することができます。
私たちは、交換されているものとは何かを理解する必要があります。だけではなく、数字0 0非デジタルの交換。これは、内部にデジタル非ゼロ非ゼロ領域を交換することによって交換されます。
したがって、左右のオープンおよび非0の数の範囲の内側に閉じ[0、nonZeroIndex)で発現された非ゼロ範囲[0、nonZeroIndex)を定義します。
例の結果
class Solution {
public void moveZeroes(int[] nums) {
int nonZeroIndex = 0;//[0,nonZeroIndex)为非0的范围
for(int i=0;i<nums.length;i++){
if(nums[i] !=0){
swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
nonZeroIndex++;//非0区域扩大
}
}
}
private void swap(int a,int b,int[] nums){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
特別なシーンの最適化
这里可能的特殊场景为 nums数组里面全为非0的数字,这样每一次都是自己与自己进行交换操作。如果需要考虑这种极端场景的话,就需要加多一步判断。
//考虑极端条件nums全部为非0时候,
if(i != nonZeroIndex) {
swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
nonZeroIndex++;//非0区域扩大
}else{
nonZeroIndex++;
}
コードこのようなシナリオは以下のとおりです。
class Solution {
public void moveZeroes(int[] nums) {
int nonZeroIndex = 0;//[0,nonZeroIndex)为非0的范围
for(int i=0;i<nums.length;i++){
if(nums[i] !=0){
//考虑极端条件nums全部为非0时候
if(i != nonZeroIndex) {
swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
nonZeroIndex++;//非0区域扩大
}else{
nonZeroIndex++;
}
}
}
}
private void swap(int a,int b,int[] nums){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}