Related
The my goal is to take a user's input and rotate the array however many times based off of their integer input. At first I was trying to get the array to reverse just to see it shift but I have a few errors in my function that won't let me compile.
Edit: I know I used list instead of using arr. I was looking at an example and accidentally typed it in.
Here is my code:
import java.util.Scanner;
public class Project1P2 {
public static void main(String[] args) {
int[] arr1 = {2,4,6,8,10,12};
int[] arr2 = shift(arr1);
Scanner input = new Scanner(System.in);
System.out.print("Here is the Array: " + arr1);
System.out.println("Enter a number to shift array: ");
int n = input.nextInt();
}
public static int[] shift(int[] arr) {
int[] arrShiftDone = new int[list.length];
for (int i = 0, j = arrShiftDone.length - 1; i < list.length; i++, j--) {
arrShiftDone[j] = list[i];
}
return arrShiftDone;
}
}
You need to fix a couple of things:
shift method never gets called from the main method, which means it won't do anything to the array
shift method should have another argument for the number of places to shift, say n
In shift method, you are using list whereas the argument is declared as arr
Below is an example method that shifts the array:
public static int[] shift(int[] arr, int n) {
if(n > arr.length)
n = n%arr.length;
int[] result = new int[arr.length];
for(int i=0; i < n; i++){
result[i] = arr[arr.length-n+i];
}
int j=0;
for(int i=n; i<arr.length; i++){
result[i] = arr[j];
j++;
}
return result;
}
The compilation error is because the variable list is unknown. Should be using the argument arr instead of list inside the method shift(int[] arr).
You can use Arrays.stream(int[],int,int) method twice to get two streams with the specified ranges of the array: near and far, then swap them and concat back into one stream, and thus get a shifted array:
public static int[] shiftArray(int[] arr, int n) {
return IntStream
.concat(Arrays.stream(arr, n, arr.length),
Arrays.stream(arr, 0, n))
.toArray();
}
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
System.out.println("Source array: " + Arrays.toString(arr1));
System.out.println("Enter a number: ");
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] arr2 = shiftArray(arr1, n % arr1.length);
System.out.println("Shifted array: " + Arrays.toString(arr2));
}
Output:
Source array: [2, 4, 6, 8, 10, 12]
Enter a number:
3
Shifted array: [8, 10, 12, 2, 4, 6]
See also: Place positive numbers before negative
Your mistake is that in your shift method you are using list, it should be arr. I have updated it below. I have also included the shift method.
Edited to include negative shifts.
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
int[] arr2 = reverseArray(arr1);
Scanner input = new Scanner(System.in);
System.out.println("Here is the Array: " + Arrays.toString(arr1));
System.out.print("Enter a number to shift array: ");
int n = input.nextInt();
int[] arr3 = shiftArray(arr1, n);
System.out.println("Here is the shifted Array: " + Arrays.toString(arr3));
}
public static int[] reverseArray(int[] arr) {
int[] arrShiftDone = new int[arr.length];
for (int i = 0, j = arrShiftDone.length - 1; i < arr.length; i++, j--) {
arrShiftDone[j] = arr[i];
}
return arrShiftDone;
}
public static int[] shiftArray(int[] arr, int shift) {
int[] arrShiftDone = new int[arr.length];
shift = shift % arr.length;
if (shift < 0) {
shift = arr.length + shift;
}
for (int i = 0 + shift, j = 0; j < arr.length; i++, j++) {
if (i >= arr.length) {
arrShiftDone[j] = arr[i - arr.length];
} else {
arrShiftDone[j] = arr[i];
}
}
return arrShiftDone;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
Task is to find the first element of an array that is not consecutive.
E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that's the first non consecutive number.
If the whole array is consecutive then return null
Here is my solution:
import java.util.ArrayList;
import java.util.List;
class FirstNonConsecutive {
private static int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
private static List<Integer> list = new ArrayList<Integer>();
private static Integer[] arrtwovalues = new Integer[arr.length];
private static Integer solve;
static Integer find(final int[] array) {
int[] temp = new int[array.length];
int possition = array[0];
for (int i = 0; i < array.length - 1; i++) {
temp[i] = array[i + 1];
}
for (int i = 0; i < temp.length; i++) {
if (temp[i] == 0) {
temp[i] = possition;
}
}
for (int i = 0; i < array.length; i++) {
if (temp[i] - array[i] == 2) {
arrtwovalues[i] = temp[i];
}
}
for (int i = 0; i < array.length; i++) {
if (temp[i] - array[i] == 2) {
arrtwovalues[i] = temp[i];
}
}
int counter = 0;
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
counter++;
}
}
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
list.add(arrtwovalues[i]);
}
}
for (int i = 0; i < list.size(); i++) {
if (list.size() > 0) {
solve = list.get(0);
}
}
System.out.println(solve);
if (list.size() > 0) {
return solve;
}
else return null;
}
public static void main(String[] args) {
find(arr);
}
}
This is my tests:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public final class FirstNonConsecutiveTest {
#Test public void basicTests() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
}
}
This test does not pass:
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
java.lang.AssertionError:
Expected :null
Actual :6
<Click to see difference>
Process finished with exit code -1
As it says: Expected :null and Actual :6
But if I try that test-case with my main method then it returns 6 correctly and everything seems to work correctly.
Why does my test not pass? What did I miss?
Your code is way to much complicated for this task. Try something simpler to avoid mistakes, like this :
find(int[] arr) {
if(arr.length > 0) {
for(int i=1; i<arr.length; i++) {
if(arr[i]-1 != arr[i-1]){
System.out.println("The element " + arr[i] + " at the index " + i + " is the first not consecutive element of the array";
return arr[i];
}
}
}
return null; //If we reach the end of the loop, there is no number not consecutive to a previous one.
}
Currently your problem is that arrtwovalues and solve are static. So when you run your first test, you enter some values inside them. And when you run your second test, they still contain these values so it returns previous value : 6.
When you manually test your code, it return null because you did not make the first test before, so arrtwovalues and solve are not already containing values.
Because of this:
private static int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
private static List<Integer> list = new ArrayList<Integer>();
private static Integer[] arrtwovalues = new Integer[arr.length];
First of all, the variable arrtwovalues depends on the size of arr.length, which is always the same. Additionally, these values are not reset between the test runs as all of your testing code is inside the same method.
Put these variables as local variables inside your method instead and use the array.length instead:
static Integer find(final int[] array) {
List<Integer> list = new ArrayList<Integer>();
Integer[] arrtwovalues = new Integer[array.length];
int[] temp = new int[array.length];
...
This will solve that test-case, but you have one more failing test-case:
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
Which seems to be caused by your code handling 0 as a special case and returning null in that case.
It would be better to put each test-case in its own method annotated by #Test, like this:
#Test
public void basicTests1() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
}
#Test
public void basicTests2() {
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
}
#Test
public void basicTests3() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
}
#Test
public void basicTests4() {
assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
}
#Test
public void basicTests5() {
assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
}
#Test
public void basicTests6() {
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
}
#Test
public void basicTests7() {
assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
}
You code looks complicated for this simple problem. This would do the job
public Integer findFirstNonConsecutiveNumber(int[] arr){
int element=-1;
boolean found=false;
;
for(int i=1;i < arr.length;i++){
int prev=arr[i-1];
if(arr[i]!=prev + 1)
{
element=arr[i];
found=true;
break;
}
}
if(found)
return element;
else
return null;
}
replace all field in to the method itself, and past all test.
import java.util.ArrayList;
import java.util.List;
class FirstNonConsecutive {
static Integer find(final int[] array) {
List<Integer> list = new ArrayList<Integer>();
Integer[] arrtwovalues = new Integer[array.length];
Integer solve = null;
int[] newtemp = new int[array.length];
for (int i = 0; i < array.length - 1; i++) {
newtemp[i] = array[i + 1];
}
for (int i = 0; i < array.length; i++) {
if (newtemp[i] - array[i] == 2) {
arrtwovalues[i] = newtemp[i];
}
}
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
list.add(arrtwovalues[i]);
}
}
for (int i = 0; i < list.size(); i++) {
if (list.size() > 0) {
solve = list.get(0);
}else solve = null;
}
return solve;
}
public static void main(String[] args) {
int[] arr = new int[]{4, 6, 7, 8, 9, 11};
System.out.println(find(arr));
}
}
Give it a try with the following find() method:
public Integer find(final int[] array) {
Integer val = null; // 1
for (int i = 0; i < array.length - 1; i++) { // 2
int current = array[i]; // 3
int next = array[i + 1]; // 4
if (current + 1 != next) { // 5
val = next; // 6
break; // 7
}
}
return val; // 8
}
1 - Initializing the Integer variable "val" as null.
2 - i = 0 means that the loop will start from the first element of the input "array". "i < array.length - 1" means that the loop will continue till the second last element of the array or in other words the loop will exclude the last element.
3 - Current element of the array
4 - Next element of the array
5 - Consecutive means (current + 1 = next). This if condition is checking for the not-consecutive element.
6 - If the not consecutive element is found then it is stored into the "val" variable.
7 - Since the not consecutive element is found it is not required to check the rest of the elements.
8 - If the not consecutive element is found (6) then that element will be returned, otherwise null (1) will be returned.
My program is supposed to take a provided array and create a new array where each element is the sum of the previous elements in original array. For example element one in new array is element one in original array. Element two in new array is sum of element one an element two in original array. Element three in new array is sum of elements one, two and three in original array. I wrote this but I know it is incomplete. Please guide.
public class PrefixSum
{
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x = array[i];
x = x + i;
}
newArray[0] = 0;
System.out.println(" " + newArray[x]);
}
}
You can use a variable runningTotal to keep count of the running total like so:
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int[] originalArray = new int[]{0,5,1,-3,2,0,4};
int[] sumArray = new int[originalArray.length];
int runningTotal = 0;
for(int i = 0; i < originalArray.length; i++){
runningTotal += originalArray[i];
sumArray[i] = runningTotal;
}
System.out.println("The originalArray is: " + Arrays.toString(originalArray));
System.out.println("The sumArray is: " + Arrays.toString(sumArray));
}
}
Output:
The originalArray is: [0, 5, 1, -3, 2, 0, 4]
The sumArray is: [0, 5, 6, 3, 5, 5, 9]
Try it here!
You may Debug this code in order to understand the changes.
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x += array[i];
newArray[i] = x;
}
}
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int sum = 0;
for(int i = 0; i < array.length; i++)
{
sum += array[i];
newArray[i]= sum;
System.out.println(" " +newArray[i]);
}
}
List<Integer> sums = new ArrayList<>();
Stream.of(0, 5, 1, -3, 2, 0, 4).reduce((left, right) -> {
sums.add(left + right);
return left + right;
});
Printing sums after running yields :
[0, 5, 6, 3, 5, 5, 9]
Try it here.
Array with duplicates [4,4,1]. Find pairs with sum 5 in O(n).
Expected output (4,1) and (4,1) and count is 2.
Approach#1:
Using HashSet:
public static int twoSum(int[] numbers, int target) {
HashSet<Integer> set = new HashSet<Integer>();
int c = 0;
for(int i:numbers){
if(set.contains(target-i)){
System.out.println(i+"-"+(target-i));
c++;
}
set.add(i);
}
return c;
}
Output is 1.
Approach #2 as stated in this link:
private static final int MAX = 100000;
static int printpairs(int arr[],int sum)
{
int count = 0;
boolean[] binmap = new boolean[MAX];
for (int i=0; i<arr.length; ++i)
{
int temp = sum-arr[i];
if (temp>=0 && binmap[temp])
{
count ++;
}
binmap[arr[i]] = true;
}
return count;
}
Output 1.
However the O(nlog n) solution is using sorting the array:
public static int findPairs(int [] a, int sum){
Arrays.sort(a);
int l = 0;
int r = a.length -1;
int count = 0;
while(l<r){
if((a[l] + a[r]) == sum){
count ++;
System.out.println(a[l] + " "+ a[r]);
r--;
}
else if((a[l] + a[r])>sum ){
r--;
}else{
l++;
}
}
return count;
}
Can we get the solution in O(n)?
You can use your second approach - just change boolean to int:
public static void main(String[] args) {
System.out.println(printPairs(new int[]{3, 3, 3, 3}, 6)); // 6
System.out.println(printPairs(new int[]{4, 4, 1}, 5)); // 2
System.out.println(printPairs(new int[]{1, 2, 3, 4, 5, 6}, 7)); // 3
System.out.println(printPairs(new int[]{3, 3, 3, 3, 1, 1, 5, 5}, 6)); // 10
}
public static int printPairs(int arr[], int sum) {
int count = 0;
int[] quantity = new int[sum];
for (int i = 0; i < arr.length; ++i) {
int supplement = sum - arr[i];
if (supplement >= 0) {
count += quantity[supplement];
}
quantity[arr[i]]++; // You may need to check that arr[i] is in bounds
}
return count;
}
you can try this also
Map<Integer, List> map = new HashMap<>();
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(k - arr[i])) {
count += map.get(k - arr[i]).size();
}
List<Integer> test = map.getOrDefault(arr[i], new ArrayList<>());
test.add(i);
map.put(arr[i], test);
}
return count;
Here is an O(N) Time & Space approach using HashMap.
class Solution
{
static int getPairsCount(int[] arr, int n, int target)
{
HashMap<Integer,Integer> map = new HashMap<>();
int pairs=0;
for (int i=0; i<n; i++)
{
if (map.containsKey(target - arr[i]))
{
pairs += map.get(target - arr[i]);
for (int j=1; j<=map.get(target - arr[i]); j++)
System.out.print("(" +(target-arr[i])+ "," +arr[i]+ ") ");
}
map.put(arr[i] , map.getOrDefault(arr[i],0)+1);
}
return pairs;
}
public static void main (String [] args)
{
int target = 5;
int [] input = {4, 4, 1};
System.out.println(getPairsCount(input , input.length , target));
target = 10;
input = new int [] {1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1};
System.out.println(getPairsCount(input , input.length , target));
}
}
Output:
2 (Pairs)
(4,1) (4,1)
13 (Pairs)
(5,5) (3,7) (2,8) (6,4) (2,8) (8,2) (8,2) (5,5) (5,5) (1,9) (1,9) (9,1) (9,1)
I need to efficiently sort through 4 arrays and return 2 results.
The first result will contain all numbers that exist in the arrays.
The second result will contain, all occurrences of each number in the result
int[] a = [1,2,3,4,5];
int[] b = [1,2,3,4,5,6];
int[] c = [1,3,7];
int[] d = [2,3,4,8,9,10];
int[] result1 = [1,2,3,4,5,6,7,8,9,10];
int[] result2 = [1,1,1,2,2,2,3,3,3,3,4,4,4,5,5,6,7,8,9,10];
Step 1: Combine all the arrays
Step 2: Sort arrays using Arrays.sort(array);
Step 3: Remove the duplicates.
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
int[] c = {1,3,7};
int[] d = {2,3,4,8,9,10};
int[] resultArray1 = new int[a.length+b.length+c.length+d.length];
int arrayIndex = 0;
for (int i=0; i< a.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = a[i];
}
for (int i=0; i< b.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = b[i];
}
for (int i=0; i< c.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = c[i];
}
for (int i=0; i< d.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = d[i];
}
// Sorting Arrays
System.out.println("Array before Sort"+Arrays.toString(resultArray1));
Arrays.sort(resultArray1);
System.out.println("Array after Sort"+Arrays.toString(resultArray1));
// Removing duplicates
Set<String> set = new HashSet<String>();
for (int i = 0; i < resultArray1.length; i++) {
set.add(""+resultArray1[i]); // To convert to string
}
String[] uniqueStringArray = set.toArray(new String[set.size()]); ;
int [] uniqueIntArray = new int [uniqueStringArray.length];
// Converting string array to int array
for(int i=0;i<uniqueStringArray.length;i++)
{
uniqueIntArray[i]= Integer.parseInt(uniqueStringArray[i]);
}
Arrays.sort(uniqueIntArray);
System.out.println("Unique Array after Sort"+Arrays.toString(uniqueIntArray));
Output:
Array before Sort[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 3, 7, 2, 3, 4, 8, 9, 10]
Array after Sort[1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10]
Unique Array after Sort[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Combine all 4 arrays in 1 array
sort Array
Remove Dublicate from array
import java.util.Vector;
class sort
{
public static void main(String args[])
{
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
int[] c = {1,3,7};
int[] d = {2,3,4,8,9,10};
int[] s = combine(a,b,c,d); //concate array using concate function
int[] sort = sort(s);//sort array using sort function
//SORTING ARRAY
System.out.print("ARRAY AFTER SORT ");
System.out.print("[");
for(int i=0;i<sort.length;i++)
{
if(i==sort.length-1)
System.out.print(sort[i]);
else
System.out.print(sort[i]+",");
}
System.out.println("]\n");
//REMOVE DUPLICATE
int[] removedups=removedups(sort);// Remove Duplicate item from array using removedups
System.out.print("ARRAY REMOVE DUPLICATE ");
System.out.print("[");
for(int i=0;i<removedups.length;i++)
{
if(i==removedups.length-1)
System.out.print(removedups[i]);
else
System.out.print(removedups[i]+",");
}
System.out.print("]");
}
public static int[] combine(int a[],int b[],int c[],int d[])//combine array
{
int sort []=new int[a.length+b.length+c.length+d.length];
int j=0;
for(int i=0;i<a.length;i++)
{
sort[j]=a[i];
j++;
}
for(int i=0;i<b.length;i++)
{
sort[j]=b[i];
j++;
}
for(int i=0;i<c.length;i++)
{
sort[j]=c[i];
j++;
}
for(int i=0;i<d.length;i++)
{
sort[j]=d[i];
j++;
}
return sort;
}
public static int[] sort(int s[]) // sort array
{
int temp;
for(int i=0;i<s.length;i++)
{
for(int j=i+1;j<s.length-1;j++)
{
if(s[i]>s[j])
{
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
}
}
return s;
}
public static int[] removedups(int s[])//remove dups from sorted array
{
Vector array=new Vector();
int l=0;
for(int i=0;i<s.length-1;i++)
{
if(s[i]!=s[i+1])
{
array.add(s[i]);
l++;
}
}
int[] temp=new int[array.size()];
for(int j=0;j<temp.length;j++)
{
temp[j]=Integer.parseInt(""+array.get(j));
}
return temp ;
}
}//end the program
Simpliest way is use sort and HashSet
public class SortClass {
public static void main(String[] args) {
//Define imput data
int[] a = {1, 2, 3, 4, 5};
int[] b = {1, 2, 3, 4, 5, 6};
int[] c = {1, 3, 7};
int[] d = {2, 3, 4, 8, 9, 10};
//Actual algorithm
List<Integer> all = new ArrayList<Integer>();
all.addAll(toList(a));
all.addAll(toList(b));
all.addAll(toList(c));
all.addAll(toList(d));
Collections.sort(all);
TreeSet<Integer> set = new TreeSet<Integer>();
set.addAll(all);
int[] sorted = toIntArray(all);
int[] sortedUniq = toIntArray(set);
//Output result
System.out.println("Sorted: " + Arrays.toString(sorted));
System.out.println("Sorted uniq: " + Arrays.toString(sortedUniq));
}
// We need pair of method to convert between `int[]` and `Collection<Integer>`
private static int[] toIntArray(Collection<Integer> all) {
int[] ints = new int[all.size()];
int i =0;
for (int val : all) {
ints[i] = val;
i++;
}
return ints;
}
private static Collection<? extends Integer> toList(int[] ints) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i : ints) {
list.add(i);
}
return list;
}
}
But if performance is critical we can utilize the fact that input arrays already sorted and us merge sort:
public class SortClass {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
int[] b = {1, 2, 3, 4, 5, 6};
int[] c = {1, 3, 7};
int[] d = {2, 3, 4, 8, 9, 10};
//Prepare data structure
List<ArrayTail> all = new ArrayList<ArrayTail>();
add(all, new ArrayTail(a));
add(all, new ArrayTail(b));
add(all, new ArrayTail(c));
add(all, new ArrayTail(d));
int[] sorted = sort(all);
int[] sortedUniq = getUniq(sorted);
System.out.println("Sorted: " + Arrays.toString(sorted));
System.out.println("Sorted uniq: " + Arrays.toString(sortedUniq));
}
private static int[] getUniq(int[] sorted) {
Collection<Integer> result = new ArrayList<Integer>();
int current = sorted[0];
result.add(current);
for (int i : sorted){
if(i != current){
current = i;
result.add(i);
}
}
return toIntArray(result);
}
private static int[] sort(List<ArrayTail> all) {
int totalLength = 0;
for (ArrayTail tail : all){
totalLength+=tail.size();
}
int[] result = new int[totalLength];
int pos = 0;
while(!all.isEmpty()){
//Take smallest value from smallest array
ArrayTail smallest = all.get(0);
result[pos] = smallest.take();
pos++;
// remove array if no more elements in it
if(smallest.size() ==0){
all.remove(0);
} else {
// ensure that first element steel smallest
sortFirstElement(all);
}
}
return result;
}
// This is actually on step of bubble sort, but it
// works because all other list except may be first already sorted
private static void sortFirstElement(List<ArrayTail> all) {
for (int i = 0; i < all.size()-1; i++) {
if(all.get(i).get() > all.get(i+1).get()){
Collections.swap(all, i, i + 1);
} else {
break;
}
}
}
private static void add(List<ArrayTail> all, ArrayTail arrayTail) {
// all sorted here
all.add(0, arrayTail);
sortFirstElement(all);
// all sorted here, again
}
private static int[] toIntArray(Collection<Integer> all) {
int[] ints = new int[all.size()];
int i =0;
for (int val : all) {
ints[i] = val;
i++;
}
return ints;
}
// Simpl data structure representing tail of array
private static class ArrayTail {
private final int[] arr;
private int pos;
public ArrayTail(int[] arr) {
this.arr = arr;
this.pos = 0;
}
public int size() {
return arr.length - pos;
}
public int take() {
return arr[pos++];
}
public int get() {
return arr[pos];
}
}
}
As you can see code become more complex but possible work faster.
PS: fun thing is that bubble sort can be used in real life :)
TRY Using merge sort algorithm. wikipedia page here
For result 1, dump the contents of your 4 lists into a TreeSet. This will sort and remove duplicates from the set at the same time. Then get the array of the set.
For result 2, use array copy to copy all the numbers into 1 array and then sort that array using Arrays.sort(...). There is no need to try to merge them on your own due to the nature of the sorting algorithm which is O(nlog(n)). Quadrupling the size results in a multiplying factor of only 2.