按剩余的4对数组进行排序

Ass*_*saf 4 java arrays

我有一个练习,我必须按以下方式对数组进行排序:

  1. 除以4而没有余数的数字将是数组中的第一个(例如4,8,12,16).
  2. 将剩余的1除以4的数字将是数组中的第二个(1,5,9).
  3. 将剩余的2除以4的数字将是数组中的第三个(2,6,10).
  4. 将剩下的3除以4的数字将在数组中最后.

例如,以下数组:

int []a={1,7,3,2,4,1,8,14}
Run Code Online (Sandbox Code Playgroud)

将会:

4   8   1   1   2   14  3   7   
Run Code Online (Sandbox Code Playgroud)

组内的顺序无关紧要.

我找到了一个解决O(n)时间复杂度和O(1)空间复杂度的解决方案.

然而,它是丑陋的,并在阵列上移动3次.我想要一个更优雅的解决方案.

这是我的代码:

    int ptr=a.length-1; int temp=0, i=0;
    while (i<ptr){
        //move 3 remained to the end
        if (a[i] % 4==3){
            temp=a[ptr];
            a[ptr]=a[i];
            a[i]=temp;
            ptr--;
        }
        else
            i++;
    }
    i=0;
    while (i<ptr){
        if (a[i]%4==2)
        {
            temp=a[ptr];
            a[ptr]=a[i];
            a[i]=temp;
            ptr--;
        }
        else
            i++;
    }
    i=0;
    while (i<ptr){
        if (a[i]%4==1)
        {
            temp=a[ptr];
            a[ptr]=a[i];
            a[i]=temp;
            ptr--;
        }
        else
            i++;
    }
Run Code Online (Sandbox Code Playgroud)

重要的是要知道:

  • 我不希望时间复杂度比O(n)差,并且空间复杂度比O(1)差.

zw3*_*324 6

由于O(3*N)是O(N),你只需要遍历数组三次:

  1. 将元素e % 4 == 0移到前面,沿途交换元素;
  2. 将元素e % 4 == 1移到前面,沿途交换元素;
  3. 将元素e % 4 == 2移到前面,沿途交换元素;

e % 4 == 3在此之后将会结束的元素.

例:

public static void main(String args[]) {
    int[] a = { 1, 7, 3, 2, 4, 1, 8, 14 , 9};
    int current = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = current; j < a.length; j++) {
            if (a[j] % 4 == i) {
                int b = a[j];
                a[j] = a[current];
                a[current] = b;
                current++;
            }
        }
    }
    System.out.println(Arrays.toString(a));
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过跟踪已经移动到前面的给定余数的元素数量来优化这一点,并且仅循环过去那些元素.我想基本上做`for(int j = current; ...)`应该做的伎俩. (3认同)
  • 世界上最小的挑剔:似乎既不需要"当前"和"开始".其中一个,在外循环之前初始化为'0`应该就足够了. (2认同)