将0移动到数组的末尾

时间:2013-04-01 19:27:37

标签: java arrays

我需要将数组中的所有0移动到数组的末尾。

示例:[1,10,0,5,7]应该产生[1,10,5,7,0]。

我愿意做反向循环或常规循环。

无法创建新数组。

这是我到目前为止所做的:

for (int i = arr.length; i <= 0; --i) {
    if (arr[i] != 0) {
        arr[i] = arr.length - 1;
    }
}

谢谢!

22 个答案:

答案 0 :(得分:13)

SIZE(n)其中n = arr.size,保留排序:

创建一个与您需要删除0的初始数组大小相同的数组。迭代原始数组并将每个元素添加到新数组中,前提是它不是0.当遇到0时,计算它。现在,当您到达第一个数组的末尾时,只需将计数的0数添加到数组的末尾即可。而且,甚至更简单,因为Java将数组初始化为0,您可以忘记在最后添加零。


修改

由于您添加了无法创建新数组的附加约束,因此我们需要采用与上面建议的方法略有不同的方法。

SIZE(1)

我认为数组需要保持与0移动到结尾之前相同的顺序。如果不是这种情况,则有另一个简单的解决方案,详见Brads的答案:将“last zero”索引初始化为数组的最后一个元素,然后向后迭代,使用最后一个零的索引交换任意零,每次递减你执行交换或看到零。

SIZE(1),保留排序:

要将0移动到最终而不复制数组并保持元素的正确顺序,您可以完全按照我的建议执行操作,而不会复制数组但在同一个数组上保留两个索引。

从数组上的两个索引开始。如果元素不为零,则不要将元素复制到新数组,而是将其保留在原来的位置并增加两个索引。当您达到零时,只增加一个索引。现在,如果两个索引不相同,并且您没有查看0,则将当前元素交换为已落后的索引的位置(由于遇到0)。在这两种情况下,如果当前元素不为0,则递增另一个索引。

看起来像这样:

int max = arr.length;
for (int i = 0, int j = 0; j < max; j++) {
  if (arr[j] != 0) {
    if (i < j) {
      swap(arr, i, j);
    }
    i++
  }
}

运行此功能:

{ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 }

yeilds:

{ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }

我为那些好奇的人做了fully working version

答案 1 :(得分:3)

想到两个选择

  1. 创建一个大小相同的新数组,然后迭代当前数组,只用值填充新数组。然后使用“zeros”

  2. 填充新数组中的其余条目
  3. 如果不创建新数组,您可以向后迭代当前数组,当遇到“零”时,将其与数组的最后一个元素交换。您需要保持交换“零”元素数量的计数,这样当您第二次交换时,您将与last-1元素交换,依此类推。


  4. [编辑] 以下请求澄清

    public class MyClass {
    
        public static void main(String[] args) {
    
            int[] elements = new int[] {1,2,3,4,0,5,6,0,7,8,9};
    
            int swapCount = 0;
            int lastIndex = elements.length-1;
    
            for(int i = lastIndex-1; i >=0; i--) {  // skip the very last element
                if(elements[i] == 0) {
                    elements[i] = elements[lastIndex-swapCount];
                    elements[lastIndex-swapCount] = 0;
                    swapCount++;
                }
            }
    
            for(int i : elements) {
                System.out.print(i + ", ");
            }
        }
    }
    

    给你......

    1, 2, 3, 4, 8, 5, 6, 9, 7, 0, 0, 
    

答案 2 :(得分:1)

基本解决方案是建立一个归纳假设,即子阵列可以保持解决。然后将子阵列延伸一个元素并保持假设。在这种情况下,有两个分支 - 如果下一个元素为零,则不执行任何操作。如果next元素非零,则将其与行中的第一个零交换。

无论如何,在优化这个想法之后的解决方案(在C#中)看起来像这样:

void MoveZeros(int[] a)
{

    int i = 0;

    for (int j = 0; j < a.Length; j++)
        if (a[j] != 0)
            a[i++] = a[j];

    while (i < a.Length)
        a[i++] = 0;

}

有一些想法会导致这种解决方案,从可以被正式证明正确的归纳解决方案开始。如果您有兴趣,整个分析就在这里:Moving Zero Values to the End of the Array

答案 3 :(得分:1)

var size = 10;
var elemnts = [0, 0, 1, 4, 5, 0,-1];
var pos = 0;
for (var i = 0; i < elemnts.length; i++) {
    if (elemnts[i] != 0) {
        elemnts[pos] = elemnts[i];
        pos++;
        console.log(elemnts[i]);
    }
}
for (var i = pos; i < elemnts.length; i++) {
    elemnts[pos++] = 0;
    console.log(elemnts[pos]);
}

答案 4 :(得分:0)

这是我的代码,包含2个for循环:

int [] arr = {0, 4, 2, 0, 0, 1, 0, 1, 5, 0, 9,};
int temp;
for (int i = 0; i < arr.length; i++) 
{
  if (arr[i] == 0)
  {
    for (int j = i + 1; j < arr.length; j++) 
    {
      if (arr[j] != 0)
      {
        temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
        break;
      }
    }
  }
}

System.out.println(Arrays.toString(arr));

输出:[4,2,1,1,5,9,0,0,0,0,0]

答案 5 :(得分:0)

  import java.io.*;
  import java.util.*;

  class Solution {

  public static int[] moveZerosToEnd(int[] arr) {

  int j = 0;
  for(int i = 0; i < arr.length; i++) {
    if(arr[i] != 0) {
      swap(arr, i, j);
      j++;
    }
   }
    return arr;
  }
 private static void swap(int arr[], int i, int j){
      int temp = arr[j];
      arr[j] = arr[i];
      arr[i] = temp;
   }

public static void main(String[] args) {
   int arr[] =new int[] {1, 10, 0, 2, 8, 3, 0, 0, 6, 4, 0, 5, 7, 0 };
   System.out.println(Arrays.toString(moveZerosToEnd(arr)));
  }
}

答案 6 :(得分:0)

看看这个功能代码:

vector<int> Solution::solve(vector<int> &arr) {
    int count = 0;  
    for (int i = 0; i < arr.size(); i++) 
        if (arr[i] != 0) 
            arr[count++] = arr[i]; 
    while (count < arr.size()) 
        arr[count++] = 0; 
    return arr;
}

答案 7 :(得分:0)

public void test1(){

    int [] arr = {0,1,0,4,0,3,2};   
    System.out.println("Lenght of array is " + arr.length);

    for(int i=0; i < arr.length; i++){

        for(int j=0; j < arr.length - i - 1; j++){
            if(arr[j] == 0){
                int temp = arr[j];
                arr[j] = arr[arr.length - i - 1]; 
                arr[arr.length - i - 1] = temp;
            }
        }
    }

    for(int x = 0; x < arr.length; x++){
        System.out.println(arr[x]);
    }
}

答案 8 :(得分:0)

让我们说,您有一个类似的数组

int a[] = {0,3,0,4,5,6,0};

然后您可以将其排序,

   for(int i=0;i<a.length;i++){
    for(int j=i+1;j<a.length;j++){
    if(a[i]==0 && a[j]!=0){
    a[i]==a[j];
    a[j]=0;
    }
    }
    }

答案 9 :(得分:0)

对于Integer数组,它可以很简单

Integer[] numbers = { 1, 10, 0, 5, 7 };
Arrays.sort(numbers, Comparator.comparing(n -> n == 0));

对于int数组:

int[] numbers = { 1, 10, 0, 5, 7 };
 numbers = IntStream.of(numbers).boxed()
                    .sorted(Comparator.comparing(n -> n == 0))
                    .mapToInt(i->i).toArray();

两者的输出:

  

[1、10、5、7、0]

答案 10 :(得分:0)

int[] nums = {3,1,2,5,4,6,3,2,1,6,7,9,3,8,0,4,2,4,6,4};
    int i = 0;
    for(int j = 0, s = nums.length; j < s;) {
        if(nums[j] == 3)
            j++;
        else {
            int temp = nums[i];
            nums[i] = nums[j];``
            nums[j] = temp;
            i ++;
            j ++;
        }
    }

答案 11 :(得分:0)

yield

}

答案 12 :(得分:0)

     public static void main(String[] args) {
            Integer a[] = {10,0,0,0,6,0,0,0,70,6,7,8,0,4,0};
            int flag = 0;int count =0;
                for(int i=0;i<a.length;i++) {
                if(a[i]==0 ) {
                    flag=1;
                    count++;
                }else if(a[i]!=0) {
                    flag=0;
                }
                if(flag==0 && count>0 && a[i]!=0) {
                    a[i-count] = a[i];
                    a[i]=0;
                }
            }
}

答案 13 :(得分:0)

这是将零移动到数组末尾的一种方法。

public class SeparateZeroes1  {

    public static void main(String[] args) {

        int[] a = {0,1,0,3,0,0,345,12,0,13};

        movezeroes(a);      
    }

    static void movezeroes(int[] a) {
        int lastNonZeroIndex = 0;
     // If the current element is not 0, then we need to
        // append it just in front of last non 0 element we found.
    for (int i = 0; i < a.length; i++) {
        if (a[i]  != 0 ) {
            a[lastNonZeroIndex++] = a[i];
        }
    }//for


    // We just need to fill remaining array with 0's.
    for (int i = lastNonZeroIndex; i < a.length; i++) {
        a[i] = 0;
    }   
   System.out.println( lastNonZeroIndex         );
 System.out.println(Arrays.toString(a));

    }
}

这在Python中非常简单。我们将使用列表理解来实现它

a =[0,1,0,3,0,0,345,12,0,13]
def fix(a):
    return ([x for x in a if x != 0] + [x for x in a if x ==0])

print(fix(a))

答案 14 :(得分:0)

以下是我如何实现这一点。 时间复杂度:O(n)和空间复杂度:O(1) 以下是代码段:

int arr[] = {0, 1, 0, 0, 2, 3, 0, 4, 0};
int i=0, k = 0;
int n = sizeof(arr)/sizeof(arr[0]);
for(i = 0; i<n; i++)
{
  if(arr[i]==0)
    continue;
  arr[k++]=arr[i];
}
for(i=k;i<n;i++)
{
  arr[i]=0;
}

output: {1, 2, 3, 4, 0, 0, 0, 0, 0}

说明:使用另一个变量k来保存索引位置,非零元素在保持顺序的同时被移到前面。遍历数组后,非零元素移位到数组的前面,另一个从k开始的循环用于覆盖剩余的零位。

答案 15 :(得分:0)

让我们说我们有一个数组

[5,4,0,0,6,7,0,8,9]

假设我们有0-100之间的数组元素,现在我们的目标是将所有0都移到数组的末尾。 现在从数组中保持0并使用非零元素检查它是否有任何非零元素与该元素交换,依此类推,在循环结束时我们将找到解决方案。

这是代码

for (int i = 0; i < outputArr.length; i++) 
  {

      for (int j = i+1; j < outputArr.length; j++) 
  {
        if(outputArr[i]==0 && outputArr[j]!=0){

            int temp = outputArr[i];
            outputArr[i] = outputArr[j];
            outputArr[j] = temp;

        }

     }
        print outputArr[i]....
}

<强>输出:

[5,4,6,7,8,9,0,0,0]

答案 16 :(得分:0)

时间复杂度= O(n),空间复杂度= O(1)

import java.util.Scanner;

public class ShiftZeroesToBack {

    int[] array;
    void shiftZeroes(int[] array) {

        int previousK = 0; 
        int firstTime = 0;

        for(int k = 0; k < array.length - 1; k++) {

            if(array[k] == 0 && array[k + 1] != 0 && firstTime != 0) {
                int temp = array[previousK];
                array[previousK] = array[k + 1];
                array[k + 1] = temp;
                previousK = previousK + 1;
                continue;
            }

            if(array[k] == 0 && array[k + 1] != 0) {
               int temp = array[k];
               array[k] = array[k + 1];
               array[k + 1] = temp;
               continue;
            }

            if(array[k] == 0 && array[k + 1] == 0) {
                if(firstTime == 0) {
                    previousK = k; 
                    firstTime = 1;
                }
            }

       }
   }

   int[] input(Scanner scanner, int size) {
       array = new int[size];
       for(int i = 0; i < size; i++) {
           array[i] = scanner.nextInt();
       }
       return array;
   }

   void print() {
       System.out.println();
       for(int i = 0; i < array.length; i++) {
           System.out.print(array[i] + " ");
       }
       System.out.println();
   }

   public static void main(String[] args) {
       Scanner scanner = new Scanner(System.in);
       ShiftZeroesToBack sztb = new ShiftZeroesToBack();
       System.out.print("Enter Size of Array\t");
       int size = scanner.nextInt();
       int[] input = sztb.input(scanner, size);
       sztb.shiftZeroes(input);
       sztb.print();
   }

}

答案 17 :(得分:0)

如果问题添加以下条件。

  1. 时间复杂度必须为O(n) - 您只能迭代一次。
  2. 附加 空间复杂度必须为O(1) - 您无法创建额外的数组。
  3. 然后以下实施将正常工作。

    要遵循的步骤:

    1. 遍历数组&amp;保持非零元素的数量。
    2. 每当我们遇到一个非零元素放在数组中的计数位置时也增加了数量。
    3. 一旦迭代完成数组,就将零置于数组的末尾,直到计数达到数组的原始长度。
    4. public static void main(String args[]) {
        int[] array = { 1, 0, 3, 0, 0, 4, 0, 6, 0, 9 };
        // Maintaining count of non zero elements
        int count = -1;
        // Iterating through array and copying non zero elements in front of array.
        for (int i = 0; i < array.length; i++) {
            if (array[i] != 0)
                array[++count] = array[i];
        }
        // Replacing end elements with zero
        while (count < array.length - 1)
            array[++count] = 0;
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
      }
      

答案 18 :(得分:0)

/// <summary>
/// From a given array send al zeros to the end (C# solution)
/// </summary>
/// <param name="numbersArray">The array of numbers</param>
/// <returns>Array with zeros at the end</returns>
public static int[] SendZerosToEnd(int[] numbersArray)
{
    // Edge case if the array is null or is not long enough then we do
    // something in this case we return the same array with no changes
    // You can always decide to return an exception as well
    if (numbersArray == null ||
        numbersArray.Length < 2)
    {
        return numbersArray;
    }

    // We keep track of our second pointer and the last element index
    int secondIndex = numbersArray.Length - 2,
        lastIndex = secondIndex;

    for (int i = secondIndex; i >= 0; i--)
    {
        secondIndex = i;

        if (numbersArray[i] == 0)
        {
            // While our pointer reaches the end or the next element
            // is a zero we swap elements
            while (secondIndex != lastIndex ||
                numbersArray[secondIndex + 1] != 0)
            {
                numbersArray[secondIndex] = numbersArray[secondIndex + 1];
                numbersArray[secondIndex + 1] = 0;

                ++secondIndex;
            }
            // This solution is like having two pointers
            // Also if we look at the solution you do not pass more than 
            // 2 times actual array will be resume as O(N) complexity 
        }
    }
    // We return the same array with no new one created
    return numbersArray;
}

答案 19 :(得分:0)

在Python中重新实现了这个:

Pythonic方式:

lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]

for i, val in enumerate(lst):
  if lst[i] == 0:
    lst.pop(i)
    lst.append(0)

print("{}".format(lst))

@ dcow在python中的实现:

lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]

i = 0                      # init the index value
for j in range(len(lst)):  # using the length of list as the range
  if lst[j] != 0:
    if i < j: 
      lst[i], lst[j] = lst[j], lst[i]  # swap the 2 elems.
  i += 1

 print("{}".format(lst))

答案 20 :(得分:0)

int arrNew[] = new int[arr.length];
int index = 0;
for(int i=0;i<arr.length;i++){
    if(arr[i]!=0){
       arrNew[index]=arr[i];
       index++;
    }
}

因为int的数组被初始化为零(根据language spec)。这将产生你想要的效果,并将按顺序移动其他所有内容。

编辑:根据您的编辑,您无法使用新阵列,此答案不能满足您的要求。你需要检查零(从数组的末尾开始并开始工作)并与数组的最后一个元素交换,然后减少你接下来交换的last-nonoo元素的索引。例如:

int lastZero = arr.length - 1;
if(arr[i] == 0){
  //perform swap and decrement lastZero by 1 I will leave this part up to you
}

答案 21 :(得分:-1)

a = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]

count = 0
for i in range(len(a)):
    if a[i] != 0:
        a[count], a[i] = a[i], a[count]
        count += 1 

print(a)
#op [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]