1

I am writing a method to check if two int arrays are a rotation of each other. For example, [4,5,6,7,1,2] is a rotation of [1,2,4,5,6,7]

public static Boolean isRotation(int[] array1, int[] array2) {
        boolean result = false;
        if(array1.length != array2.length){
            result = false;
        }
        ArrayList<Integer> alist = new ArrayList<Integer>();
        LinkedList arr2 = new LinkedList(Arrays.asList(array2));

        if(arr2.contains(array1[0])){
            Iterator x = arr2.listIterator(arr2.indexOf(array1[0]));
            while(x.hasNext()){
             alist.add(x.next());
            }
            if(!(arr2.peek().equals(array1[0]))){
                alist.add(arr2.peek());
                arr2.pollFirst();
            }
        }//end of outer if loop. 
    //Compare the arraylist to array1;
        for(int i = 0; i<array1.length; i++){
            if(array1[i] != arr2.get(i)){
                result = false;
            }
        }//end of for loop checking
        return result; 
    }//end of method;

}//end of class;

However, I keep getting errors about object and integer. In Line alist.add(x.next()); and alist.add(arr2.peek());I cannot use the add method because I get the (argument mismatch; Object cannot be converted to Integer) error; and in this line if(array1[i] != arr2.get(i)){I get the incomparable types: int and Object error.

I don't see why the object in arr2, the linkedlist isn't an integer. Can anyone please explain what is wrong?

timeRocket
  • 53
  • 1
  • 8
  • use generics and everything will be fine. – Ousmane D. Jun 10 '18 at 10:00
  • Use a typed `LinkedList` : `LinkedList arr2 = new LinkedList<>(Arrays.asList(array2));` – Yassin Hajaj Jun 10 '18 at 10:01
  • 1
    A much simpler algorithm would be to sort both arrays and then compare. It's, like, 5 LOC or so. – lexicore Jun 10 '18 at 10:10
  • @lexicore Technically a one-liner even: `array1.length == array2.length && Arrays.mismatch(Arrays.stream(array1).sorted().toArray(), Arrays.stream(array2).sorted().toArray()) == -1;` ;) – Jorn Vernee Jun 10 '18 at 10:30
  • Possible duplicate of [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Yassin Hajaj Jun 10 '18 at 10:30
  • @JornVernee how about this one liner `Arrays.sort(array1); Arrays.sort(array2); return Arrays.equals(array1, array2);` ? ehem... just joking eh ;-) – Ousmane D. Jun 10 '18 at 10:46
  • @Aominè Oh yeah... I was too caught up in trying to use `mismatch` :) – Jorn Vernee Jun 10 '18 at 10:48
  • @JornVernee Right, I see. actually, I've never seen the `mistmatch` method until now. I was searching through the java-7 and java-8 doc to find it but to no avail and then decided to check the Java-9 and there it was hiding.... thanks for mentioning it ;-) – Ousmane D. Jun 10 '18 at 10:51

3 Answers3

4

There are several issues with your code:

  1. The use of raw types yields the aforementioned error.
  2. the result variable is always false, which doesnt seem right. so double check your logic again.

That said, let's solve the raw type issue as follows with the use of generics:

ArrayList<Integer> alist = new ArrayList<>();
LinkedList<Integer> arr2 = new LinkedList<>(Arrays.asList(array2));

if(arr2.contains(array1[0])){
   Iterator<Integer> x = arr2.listIterator(arr2.indexOf(array1[0]));
   ...
   ...

At this point, there is still another issue,

the statement LinkedList<Integer> arr2 = new LinkedList<>(Arrays.asList(array2)); will not compile as array2 is of type int[] so the receiver type should be LinkedList<int[]> to make it compile but obviously that's not what you're after.

To solve the problem, you'll need to convert the int[]. you can do this as follows:

LinkedList<Integer> arr2 = Arrays.stream(array2)
                                 .boxed() 
                               .collect(Collectors.toCollection(LinkedList::new));
Ousmane D.
  • 50,173
  • 8
  • 66
  • 103
  • Thank you! I know this can be an obvious question, but I don't quite understand the difference between int[] and Integer. And what does the solution you give do? – timeRocket Jun 10 '18 at 11:12
  • @timeRocket you're more than welcome! ;-). have a read at https://stackoverflow.com/questions/12020886/how-arrays-aslistint-can-return-listint and [this](https://stackoverflow.com/questions/1467913/arrays-aslist-not-working-as-it-should). as for my solution, it basically creates [a stream](https://docs.oracle.com/javase/9/docs/api/java/util/stream/Stream.html) from the array and changes them from type `int` to `Integer` with `boxed` and then finally accumulates them to a `LinkedList` with `toCollection`. – Ousmane D. Jun 10 '18 at 11:21
  • @timeRocket `int[]` is an array of primitives whereas `Integer []` is an array of objects. you may also want to see this https://stackoverflow.com/questions/564/what-is-the-difference-between-an-int-and-an-integer-in-java-and-c – Ousmane D. Jun 10 '18 at 11:25
  • Thank you! @Aominè – timeRocket Jun 10 '18 at 12:44
2

You are using generics in ArrayList :

ArrayList<Integer> alist = new ArrayList<Integer>();

Why not using it in :

LinkedList<Integer> arr2 = new LinkedList(Arrays.asList(array2));

and

Iterator<Integer> x = arr2.listIterator(arr2.indexOf(array1[0]));

Instead

LinkedList arr2 = new LinkedList(Arrays.asList(array2));

and

Iterator x = arr2.listIterator(arr2.indexOf(array1[0]));

Another solution(not useful in your case) without generics, you have to cast each Object :

alist.add((Integer) x.next());
          ^^^^^^^^^^^^^^^^^^

alist.add((Integer) arr2.peek());
          ^^^^^^^^^

if(array1[i] != (Integer) arr2.get(i)){
                ^^^^^^^^^

Another Solution

As @Aominè and the others mention you have several issues you have to fix them, I would just to solve your problem with another way :

public static Boolean isRotation(int[] array1, int[] array2) {
    List<Integer> list1 = Arrays.stream(array1).boxed().collect(Collectors.toList());
    List<Integer> list2 = Arrays.stream(array2).boxed().collect(Collectors.toList());
    
    int size = list1.size();

    for (int i = 0; i < size; i++) {
        if (list1.equals(list2)) {
            return true;
        }
        Collections.rotate(list2, -1);
    }
    return false;
}

Consider you have this two arrays (I consider that they are not empty and have the same length)

array1 = {4, 5, 6, 7, 1, 2}
array2 = {1, 2, 4, 5, 6, 7}

for each element in array1 move it to the end and check if it is equal with the second array of not :

First iteration :

array1 = {4, 5, 6, 7, 1, 2}
array2 = {1, 2, 4, 5, 6, 7}

not equal

Second iteration :

array1 = {4, 5, 6, 7, 1, 2}
array2 = {2, 4, 5, 6, 7, 1}//move 1 to the end

not equal

Second iteration :

array1 = {4, 5, 6, 7, 1, 2}
array2 = {4, 5, 6, 7, 1, 2}//move 2 to the end

Equal(and break)

If there are no match and the Iteration is end, then return false mean not Equals

Community
  • 1
  • 1
YCF_L
  • 49,027
  • 13
  • 75
  • 115
  • Your `another solution` is wrong. It just says that the two arrays contain the same elements, not that they are rotations of each other. – NiVeR Jun 10 '18 at 10:28
  • 1
    @NiVeR given the examples in the question I believe what YCF_L suggested previously (now removed) is correct. Although his first solution doesn't prevent all the compilation errors in the code he has solved the task with the use of generics and provided _a better_ solution which the OP may consider using instead. YCF_L +1 as I don't think this post deserves a -1. ;-). – Ousmane D. Jun 10 '18 at 10:54
  • @Aominè Are you sure? To fulfill the requirement, 2 arrays must have the same permutation (starting from one, probably different position for each one of the arrays). How does sorting and comparing preserve the permutation? – NiVeR Jun 10 '18 at 10:57
  • Thank you @Aominè I appreciate it – YCF_L Jun 10 '18 at 10:58
  • @NiVeR check my solution now! – YCF_L Jun 10 '18 at 10:58
  • @YCF_L We need context for everything in this world. My comment referred to the first version, and it was wrong. – NiVeR Jun 10 '18 at 10:59
  • @NiVeR Not 100% sure as I am not the OP but sorting the two arrays and comparing seems to suffice for the example given in the post. Anyhow, more context may be needed from the OP. – Ousmane D. Jun 10 '18 at 11:00
  • @Aominè `I am writing a method to check if two int arrays are a rotation of each other`. You solve problems for the general requirement, not just for solving the given sample. – NiVeR Jun 10 '18 at 11:02
  • @NiVeR my solution now solve that problem(two int arrays are a rotation of each other) so why this down-vote? – YCF_L Jun 10 '18 at 11:03
  • 1
    @YCF_L I upvoted. I am just claryfing that the first version didn't work. – NiVeR Jun 10 '18 at 11:04
0

Because you didn't specify the Integer type paramater:

LinkedList<Integer> arr2 = new LinkedList<>(Arrays.asList(array2));
NiVeR
  • 8,872
  • 4
  • 26
  • 34
  • 1
    This won't compile as array2 is of type int not Integer. This will give you compiler time error says The constructor LinkedList(Arrays.asList(array2)) is undefined – Arnab Dhar Jun 10 '18 at 10:43