1

I have an array like this one-

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

I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array. The result should be - {3, 6, 1, 4, 2, 5}

I have this code-

int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
    for (int j = current; j < numbers.length; j++) {
        if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
            b = numbers[j];
            numbers[j] = numbers[current];
            numbers[current] = b;
            current++;
        }
    }
}

But this code does not preserve the order in which elements appear in the array. The result I got is-

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

But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?

0

4 Answers 4

1

Using stream and comparator

int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
  .boxed()
  .sorted(Comparator.comparingInt(o -> o % 3))
  .collect(Collectors.toList());

System.out.println(lst);
Sign up to request clarification or add additional context in comments.

Comments

1

In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:

public static void main(String[] args) {
    int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
    int[] result = new int[numbers.length];
    int b = 0;
    int current = 0;
    for (int i = 0; i < 3; i++) { //3 groups
        for (int j = 0; j < numbers.length; j++) {
            if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
                result[current] = numbers[j];
                current++;
            }
        }
    }

    System.out.println(Arrays.toString(result));
}

Output: [3, 6, 1, 4, 2, 5]

Comments

1

You can use an IntStream and a Comparator to sort the stream:

int[] arr = {1, 2, 3, 4, 5, 6};

int[] arrSorted = IntStream.of(arr).boxed()
        .sorted(Comparator.comparingInt(i -> i % 3))
        .mapToInt(Integer::intValue)
        .toArray();

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

Output:

[3, 6, 1, 4, 2, 5]

Note: From IntStream.of() javadoc:

Returns a sequential ordered stream whose elements are the specified values.

Comments

0

I would create a new array of the same size and then place the elements in the correct order. For example like this:

int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < array.length; j++) {
        if (array[j] % 3 == i) {
            sorted[counter] = array[j];
            counter++;
        }
    }
}
System.out.println(Arrays.toString(sorted));

Output:

[3, 6, 1, 4, 2, 5]

Alternatively, you can use Java 8 features to reduce the amount of code like this:

int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();

Output:

[3, 6, 1, 4, 2, 5]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.